Flask-Sqlalchemy .in_()方法不适用于我 [英] Flask-Sqlalchemy .in_() method not working for me

查看:337
本文介绍了Flask-Sqlalchemy .in_()方法不适用于我的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目前我正在使用Flask和SQLAlchemy开发一个项目,基本上像论坛软件一样,但是在Python 3中。

现在有两个模型,论坛和线程

我有一个应该生成论坛线程的表记录的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 ThreadsT​​able 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)

 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆