Flask-Sqlalchemy .in_()方法不适用于我 [英] Flask-Sqlalchemy .in_() method not working for me
问题描述
现在有两个模型,论坛和线程
我有一个应该生成论坛线程的表记录的Jinja模板,请看下面的内容。
{%为线程在Forum.ForumThreads.filter_by(TagID.in_(TagsToShow))中的线程%:
< TR Class =ThreadRecord>
< TD>< a href ={{thread.ForumID}} / Thread / {{thread.ThreadID}}> {{thread.Title}}< / a>< / 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'是未定义的。
我试着用 {%for thread in Forum .ForumThreads.filter_by(TagID = 1):%} ,它似乎运行良好,所以我的问题似乎是我如何调用.in_()方法。我已经搜索了SQLalchemy的文档但一直无法找到答案,任何人都可以指出我在正确的方向吗?
我不知道是否有帮助,但下面是SQLalchemy模型的两个精简版本。
class论坛(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'}
类线程(db.Model):
__tablename__ =线程
ThreadID = db.Column (db.Integer,primary_key = Tr ue)
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(
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'})
TagID
是未定义的,因为它不能直接访问。它是 Thread
模型的一部分。你需要通过 Thread
来引用它: Thread.TagID
。
然而,一旦你纠正了这个问题,你很可能会遇到一个 TypeError
。 filter_by
接受关键字参数,而不是位置参数。为了在_ 中使用进行过滤,您需要使用
过滤器
方法。 filter_by
接受关键字参数并基于此建立过滤器。
SomeModel .query.filter_by(a = 1,b = 2)
大致转换为
$ p $
SELECT * FROM somemodel WHERE a = 1 AND b = 2
另一方面,
过滤器
接受表达式(类型 BinaryExpression
)作为论据。上面的查询将表示为:
$ p $ SomeModel.query.filter(SomeModel.a == 1,SomeModel.b == 2 )
这里, SomeModel.a
是 InstrumentedAttribute
。 InstrumentedAttribute
对象拥有的方法允许您执行比较复杂的等式比较。
SomeModel.query.filter(SomeModel.a.in _((1,2)))
< (1,2)
$ c
SELECT * FROM somemodel $ c>
I'm currently working on a project with Flask and SQLAlchemy, basically forum software like discourse but in Python 3.
There are Two models at the moment, Forum and Threads
I've got a Jinja template that should be generating table records of forum threads, please see below.
{% 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 %}
This is called by the following view (slightly simplified).
@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)
However, every time I try to run it I get the error "jinja2.exceptions.UndefinedError: 'TagID' is undefined".
I've tried running it with {% for thread in Forum.ForumThreads.filter_by(TagID=1): %} and it seems to run fine, so my problem appears to be in how I am calling the .in_() method. I've searched through the documentation for SQLalchemy but have been unable to find the answer, would anyone be able to point me in the right direction?
I don't know if it helps, but below are the two stripped down versions of the SQLalchemy models used.
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'})
TagID
is undefined because it isn't directly accessible. It is part of your Thread
model. You need to go through Thread
in order to reference it: Thread.TagID
.
Once you correct this, however, you will most likely encounter a TypeError
. filter_by
accepts keyword arguments, not positional ones. In order to filter using in_
, you need to use the filter
method. filter_by
accepts keyword arguments and builds the filters based on that.
SomeModel.query.filter_by(a=1, b=2)
will roughly translate to
SELECT * FROM somemodel WHERE a = 1 AND b = 2
filter
, on the other hand, accepts expressions (type BinaryExpression
) as arguments. The above query would be expressed as
SomeModel.query.filter(SomeModel.a == 1, SomeModel.b == 2)
Here, SomeModel.a
is an InstrumentedAttribute
. InstrumentedAttribute
objects possess methods that allow you to perform comparisons that are more complex that equality.
SomeModel.query.filter(SomeModel.a.in_((1, 2)))
will roughly translate to
SELECT * FROM somemodel WHERE a IN (1, 2)
这篇关于Flask-Sqlalchemy .in_()方法不适用于我的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!