在 Flask-SQLAlchemy 中查询表的简写

Posted

技术标签:

【中文标题】在 Flask-SQLAlchemy 中查询表的简写【英文标题】:Shorthand for querying a table in Flask-SQLAlchemy 【发布时间】:2017-07-27 07:18:24 【问题描述】:

假设我有一个名为 User 的模型和一个名为 followers 的表格:

followers = db.Table(
    'followers',
    db.Column('follower_id', db.Integer, db.ForeignKey('user.id')),
    db.Column('followed_id', db.Integer, db.ForeignKey('user.id'))
)

class User(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    username = db.Column(db.String(64), index=True, unique=True)
    followed = db.relationship(
        'User',
        secondary=followers,
        primaryjoin=(followers.c.follower_id==id),
        secondaryjoin=(followers.c.followed_id==id),
        backref=db.backref('followers', lazy='dynamic'),
        lazy='dynamic'
    )

查询User模型有两种方式:

    db.session.query(User).filter(...).all() User.query.filter(...).all()

后者被认为是前者的简写,因为它们在功能上相同但更紧凑。但是,当谈到桌子时,followers.query.filter(...).all() 给了我一个错误:

AttributeError: 'Table' 对象没有属性 'query'

db.session.query(followers).filter(...).all() 有简写吗?或者,如何从table 对象中获取query 对象?

【问题讨论】:

【参考方案1】:

flask-sqlalchemy 仅在 db.Model 上定义 query,因此虽然您可以在任何子类 db.Model 上执行 Foo.query,但您不能在 Table 实例上执行相同操作。

我想你可以将它添加进去,但我不建议这样做。

【讨论】:

【参考方案2】:

添加到@univerio 答案:您可以将flask_sqlalchemy.Table 包装到您的自定义类中,而不是猴子补丁,其中将包含query 属性作为简写。

class QueryableTable:

    def __init__(self, *args, **kwargs):
        table = db.Table(*args, **kwargs)
        super().__setattr__('_flask_sa_table', table)

    @property
    def query(self):
        return db.session.query(self._flask_sa_table)

    def __getattr__(self, name):
        return getattr(self.__dict__['_flask_sa_table'], name)

    def __setattr__(self, name, value):
        return setattr(self._flask_sa_table, name, value)

将其用作followers = QueryableTable('followers', db.Column(...), ...)

【讨论】:

【参考方案3】:

您的 Follower 对象可能有问题,您可能想再次检查一下。

Follower.query.all() 应该可以工作

如果您碰巧在您的用户中与诸如此类的追随者有关系。

class User():
    followers = db.relationship("Followers", lazy='dynamic')

您可以通过以下方式执行:

user = User.query.get(id=1)
user.followers.all()

*更新

followers 表的声明不等同于您声明 User 表的方式。用户表基于 db.Model 并且 db.Model 附加了一个查询类: http://flask-sqlalchemy.pocoo.org/2.1/api/#flask.ext.sqlalchemy.Model

您也可以查看页面底部的启蒙之路部分。

http://flask-sqlalchemy.pocoo.org/2.1/quickstart/#quickstart

【讨论】:

在我的问题中,followers 不是模型User 的字段,它是一个单独的 请发布您的关注者和用户架构或表定义 已发布定义。 好的,发布后它与您声明关注者表的方式有关。我已经为你更新了答案。 Followers 表不是 db.Model 的类,这就是您无法执行查询类的原因。【参考方案4】:

要使用session.query() 方法从表中检索行,您必须将表名放在query() 中。

例如:表名“fellowers”,输入session.query(fellowers).filter_by(id = fellow_id).one()

【讨论】:

是的,没错,但我的问题是关于session.query(fellowers).filter_by(id = fellow_id).one()简写【参考方案5】:

我不确定我使用的解决方案有多传统,但我采用了pandas.read_sql_query (link),所以它或多或少是这样工作的:

pandas.read_sql_query('SELECT your_table_column from followers WHERE follower_id = your_id', your_app.config['SQLALCHEMY_DATABASE_URI'])

这为我提供了与所需 follower_id 相关的所有记录作为 pandas 数据框,可以进一步处理。

【讨论】:

以上是关于在 Flask-SQLAlchemy 中查询表的简写的主要内容,如果未能解决你的问题,请参考以下文章

Flask-Sqlalchemy:数据库查询不返回新数据

不区分大小写的数组查询Flask-SQLAlchemy

FLASK-SQLALCHEMY如何使用or和and条件进行组合查询

试图在 Flask-SQLAlchemy 中使查询不区分大小写 [重复]

Flask-SQLAlchemy精确查询&模糊查询---ORM(1)

Flask 学习-73.Flask-SQLAlchemy 分页查询paginate