【问题标题】:Flask-Sqlalchemy .in_() method not working for meFlask-Sqlalchemy .in_() 方法对我不起作用
【发布时间】:2014-09-08 20:01:15
【问题描述】:

我目前正在使用 Flask 和 SQLAlchemy 开展一个项目,基本上是类似 discourse 的论坛软件,但使用的是 Python 3。

目前有两种模式,Forum 和 Threads

我有一个 Jinja 模板,应该可以生成论坛帖子的表格记录,请参见下文。

{% for thread in Forum.ForumThreads.filter_by(TagID.in_(TagsToShow)): %}
    <TR Class="ThreadRecord">
        <TD><a href="{{thread.ForumID}}/Thread/{{thread.ThreadID}}">{{thread.Title}}</a></TD>
        <TD class="ThreadTag{{thread.TagID}}">{{thread.Tag.Name}}</TD>
        <TD>{{thread.PostList.count()}}</TD>
        <TD>{{thread.User.Name}}</TD>
        <TD>{{thread.CreationDate}}</TD>
    </TR>
{% endfor %}

这由以下视图调用(略微简化)。

@app.route('/Forum/<int:URLForumID>/ForumThreads')
    def ThreadsTable(URLForumID):
    TagsToShow = (1,2,3,4)
    Forum = models.Forum.query.filter_by(ForumID=URLForumID).first()
    return flask.render_template('ForumThreads.html', Forum=Forum, TagsToShow=TagsToShow)

但是,每次我尝试运行它时都会收到错误“jinja2.exceptions.UndefinedError: 'TagID' is undefined”。

我尝试使用 {% for thread in Forum.ForumThreads.filter_by(TagID=1): %} 运行它,它似乎运行良好,所以我的问题似乎在于我正在调用 .in_() 方法。我搜索了documentation for SQLalchemy,但一直找不到答案,有人能指出我正确的方向吗?

我不知道它是否有帮助,但下面是使用的 SQLalchemy 模型的两个精简版本。

class Forum(db.Model):
    __tablename__ = "Forum"
    ForumID = db.Column(db.Integer, primary_key=True)
    ForumName = db.Column(db.Unicode(20), unique=True, nullable=False)
    CreationDate = db.Column(db.DateTime, default=datetime.datetime.utcnow(), nullable=False)
    ForumThreads = db.relationship("Thread", backref="Forum", lazy='dynamic')
    __table_args__ = {'mysql_engine': 'InnoDB'}

class Thread(db.Model):
    __tablename__ = "Thread"
    ThreadID = db.Column(db.Integer, primary_key=True)
    ForumID = db.Column(db.Integer, db.ForeignKey("Forum.ForumID"), nullable=False)
    Title = db.Column(db.Unicode(100), nullable=False)
    UserID = db.Column(db.Integer, db.ForeignKey("User.UserID"), nullable=False)
    TagID = db.Column(db.Integer, db.ForeignKey("TagTypes.TagID"), nullable=False)
    CreationDate = db.Column(db.DateTime, default=datetime.datetime.utcnow(), nullable=False)
    __table_args__ = (db.ForeignKeyConstraint(['ForumID'], ['Forum.ForumID']),
                  db.ForeignKeyConstraint(['UserID'], ['User.UserID']),
                  db.ForeignKeyConstraint(['TagID'], ['TagTypes.TagID']),
                  {'mysql_engine': 'InnoDB'})

【问题讨论】:

    标签: python-3.x flask flask-sqlalchemy


    【解决方案1】:

    TagID 未定义,因为它不能直接访问。它是您的Thread 模型的一部分。您需要通过Thread 才能引用它:Thread.TagID

    但是,一旦您更正此问题,您很可能会遇到TypeErrorfilter_by 接受关键字参数,而不是位置参数。为了使用in_ 进行过滤,您需要使用filter 方法。 filter_by 接受关键字参数并基于此构建过滤器。

    SomeModel.query.filter_by(a=1, b=2)
    

    大概会翻译成

    SELECT * FROM somemodel WHERE a = 1 AND b = 2
    

    另一方面,filter 接受表达式(BinaryExpression 类型)作为参数。上述查询将表示为

    SomeModel.query.filter(SomeModel.a == 1, SomeModel.b == 2)
    

    这里,SomeModel.a 是一个InstrumentedAttributeInstrumentedAttribute 对象拥有允许您执行比相等更复杂的比较的方法。

    SomeModel.query.filter(SomeModel.a.in_((1, 2)))
    

    大概会翻译成

    SELECT * FROM somemodel WHERE a IN (1, 2)
    

    【讨论】:

    • 您好 Dirn,非常感谢您的回复。如果您不介意,一个简单的问题(可能不是那么快的答案):为什么我当前设置的 TagID 似乎无法访问?如果我使用单个值设置它,我可以很好地过滤,而不是使用 in_() 方法。我不怀疑,只是想知道!我已经尝试 {% for thread in Forum.ForumThreads.filter(Forum.ForumThreads.TagID.in_(TagsToShow)): %} 现在我得到以下信息: jinja2.exceptions.UndefinedError: 'sqlalchemy.orm.dynamic .AppenderBaseQuery 对象'没有属性'TagID' 我误解了答案吗?
    • 因为TagID 被用作keyword argument 的名称。
    • 如何在查询 SomeModel.query(SomeModel.Id).filter(SomeModel.a.in_((1, 2))) 中获取列值是可能的,我得到 BaseQuery 异常
    • @newuser 请提出一个包含更多详细信息的新问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-14
    • 2017-11-18
    • 2015-09-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多