Orm 炼金术中查询表的简写方法

Orm 炼金术中查询表的简写方法,orm,sqlalchemy,flask-sqlalchemy,Orm,Sqlalchemy,Flask Sqlalchemy,假设我有一个名为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.Colum

假设我有一个名为
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'
    )
有两种方法可以查询
用户
模型:

  • db.session.query(用户).filter(…).all()
  • User.query.filter(…).all()
  • 后者被认为是前者的简写,因为它们功能相同,但更紧凑。但是,当谈到表时,
    followers.query.filter(…).all()
    给了我一个错误:

    AttributeError:“表”对象没有属性“查询”

    是否有
    db.session.query(followers.filter(…).all()
    的缩写?或者,如何从
    对象中获取
    查询
    对象?

    要使用
    会话.query()
    方法从表中检索行,必须将表名放入
    查询()


    例如:对于表名“fellowers”,放置
    session.query(fellowers).filter\u by(id=fellower\u id).one()

    您的跟随者对象可能有问题,您可能想再次检查它

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

    如果您的用户碰巧与追随者有关系,例如

    class User():
        followers = db.relationship("Followers", lazy='dynamic')
    
    您可以通过以下方式执行:

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

    followers表的声明与用户表的声明方式不同。用户表基于db.Model和db.Model,其中附加了一个查询类:

    你也可以在页面底部查看启蒙之路部分


    sqlalchemy仅在
    db.Model
    上定义
    query
    ,因此,尽管您可以对子类
    db.Model
    的任何对象执行
    Foo.query
    ,但不能对
    实例执行相同的操作


    我想,您可以将其monkeypatch加入,但我不建议这样做。

    添加到@univerio答案:您可以将
    flask\u 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(…),…)
    我不确定我使用的解决方案有多传统,但我选择了
    pandas。阅读sql\u query
    (),因此它或多或少是这样工作的:

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

    这给了我所有与所需关注者id相关的记录,作为一个熊猫数据帧,可以进一步处理。

    是的,这是真的,但我的问题是关于
    会话.query(fellowers).filter by(id=fellower\u id).one()
    在我的问题中,
    关注者
    不是模型
    用户
    的字段,这是一个单独的表。请发布您的关注者和用户模式或表定义。好的,发布后,它与您如何声明关注者表有关。我已经为你更新了答案。followers表不是db.Model的类,这就是为什么不能执行查询类。