Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python SQLAlchemy:多对多关系查询中的筛选计数_Python_Sqlalchemy_Flask Sqlalchemy - Fatal编程技术网

Python SQLAlchemy:多对多关系查询中的筛选计数

Python SQLAlchemy:多对多关系查询中的筛选计数,python,sqlalchemy,flask-sqlalchemy,Python,Sqlalchemy,Flask Sqlalchemy,在我的Flask应用程序中,文档和令牌之间存在多对多关系: DocTokens = db.Table( 'DocTokens', db.Column('token_id', db.Integer, db.ForeignKey('Token.id')), db.Column('document_id', db.Integer, db.ForeignKey('Document.id')), ) class Token(db.Model): __tablena

在我的Flask应用程序中,文档和令牌之间存在多对多关系:

DocTokens = db.Table(
    'DocTokens',
    db.Column('token_id', db.Integer, db.ForeignKey('Token.id')),
    db.Column('document_id', db.Integer, db.ForeignKey('Document.id')),
    )

class Token(db.Model):
    __tablename__ = 'Token'
    id = db.Column(db.Integer, primary_key=True)
    ...
    is_gold = db.Column(db.Boolean, default=None)

class Document(db.Model):
    __tablename__ = 'Document'
    id = db.Column(db.Integer, primary_key=True)
    ...
    tokens = db.relationship(
        'Token',
        secondary=DocTokens,
        backred=db.backref('documents', lazy='dynamic'),
        )
我想构造一个文档查询,按相关令牌的数量(按降序)排序,其中Token.is\u gold为None

到目前为止,我已经了解了如何根据相关令牌的数量对文档进行排序:

db.session.query(
    Document,
    func.count(DocTokens.c.token_id).label('total')
    ).join(DocTokens).group_by(Document).order_by('total DESC')
但是,我似乎无法将Token.is_gold不包含的代币计算在内。以下是许多失败尝试之一:

db.session.query(
    Document,
    func.count(DocTokens.c.token_id)
    .filter(Token.is_gold.is_(None)).label('total')
    ).join(DocTokens).group_by(Document).order_by('total DESC')
它引发了以下错误:

AttributeError: Neither 'count' object nor 'Comparator' object has an attribute 'filter'
以下是我尝试建模的一些StackOverflow解决方案(包括涉及子查询和混合属性的解决方案):

我对SQL/SQLAlchemy相当陌生。。。非常感谢您的帮助

  • 标签
    应应用于
    函数计数(DocTokens.c.token\u id)
    ,而不是过滤器对象。您在第一个查询中正确,但在第二个查询中没有

  • filter
    是一种查询对象的方法,因此您必须将其编写为:

    db.session.query(...).join(...).filter(...).group_by(...).order_by(...)
    
  • 筛选器应用于
    标记中的列,因此必须将其包含在联接中

因此,按以下方式编写的查询不会出现错误:

r = db.session.query(Document,
                  func.count(Token.id).label('total'))\
    .join(DocTokens).join(Token)\
    .filter(Token.is_gold.is_(None))\
    .group_by(Document)\
    .order_by('total DESC')
这将生成以下sql(使用sqlite作为后端)

'选择“Document”.id作为“Document\u id”,计数(“DocTokens”.tokens\u id)作为总计\n从“token”,“Document”中加入“DocTokens”。id=“DocTokens”。Document\u id\n此处“token”。是否按“Document”为空组。id按总计描述排序'

更新:如果您不确定将从查询对象生成什么样的sql,您可以始终使用
str
,即


如果在我的示例查询中运行
str(r)
,它会打印上面引用的sql。

您能用普通sql表达您的查询吗?感谢您在我回答您的评论之前回答这个问题。我尝试了几个小时来制定sql,但我无法让它工作。。。非常感谢你!