SQLAlchemy 多对多动态延迟加载不返回 AppenderQuery
SQLAlchemy many to many dynamic lazyload not returning AppenderQuery
我正在尝试掌握 SQLAlchemy ORM 的 backref lazyload 动态特性。
我有 3 张桌子和两张 link 桌子。
course_members = Table('course_members', Base.metadata,
Column('user_id', Integer, ForeignKey('users.id')),
Column('course_id', Integer, ForeignKey('courses.id'))
)
course_roles = Table('course_roles', Base.metadata,
Column('role_id', Integer, ForeignKey('roles.id')),
Column('course_id', Integer, ForeignKey('courses.id'))
)
class User(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(200), nullable=False)
class Course(Base, Jsonify):
id = Column(Integer, primary_key=True, autoincrement=True)
members = relationship('User', secondary=course_members, backref=backref('courses', lazy='dynamic'))
roles = relationship('Role', secondary=course_roles, backref=backref('roles', lazy='dynamic'))
class Role(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
role_id = Column(Integer, nullable=False)
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship('User', backref=backref("roles", lazy='dynamic'))
UniqueConstraint('role_id', 'user_id', name='role_combination')
有用户查询:
print(type(user.roles))
print(user.roles.filter_by(id=1).first())
# print(user.courses.first() <-- Works fine too.
<class 'sqlalchemy.orm.dynamic.AppenderQuery'>
{id: 1, 'user_id': 1, role_id: 3}
但是对于课程查询:
print(type(course.roles))
print(course.roles.filter_by(id=1).first())
<class 'sqlalchemy.orm.collections.InstrumentedList'>
AttributeError: 'InstrumentedList' object has no attribute 'filter_by'
我尝试使用成员时结果相同。
使用会员和课程作为工作的列表对象:
course.roles[0].user.first()
但是我真的很想念 AppenderQuery class 用于我的课程查询的功能。
这是正常行为还是我遗漏了什么?
在撰写问题和进行研究时,我在 post add dynamic to the other side.
中找到了问题的答案
看到答案后,我对关系功能也有了更多了解。
members = relationship('User', secondary=course_members, lazy='dynamic', backref=backref('courses', lazy='dynamic'))
roles = relationship('Role', secondary=course_roles, lazy='dynamic', backref=backref('roles', lazy='dynamic'))
成员和角色关系是父 class 的功能,backref=* 是子 class 的关系功能。我花了比我喜欢的更多的时间来意识到这一点。但是通过将 lazy='dynamic' 作为关系函数中的参数,以及 backref 参数的 backref 函数有效地将其应用于关系的双方。
现在用户、课程和角色作为 AppenderQuery 返回。
希望这能帮助其他人寻找问题。
我正在尝试掌握 SQLAlchemy ORM 的 backref lazyload 动态特性。
我有 3 张桌子和两张 link 桌子。
course_members = Table('course_members', Base.metadata,
Column('user_id', Integer, ForeignKey('users.id')),
Column('course_id', Integer, ForeignKey('courses.id'))
)
course_roles = Table('course_roles', Base.metadata,
Column('role_id', Integer, ForeignKey('roles.id')),
Column('course_id', Integer, ForeignKey('courses.id'))
)
class User(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
name = Column(String(200), nullable=False)
class Course(Base, Jsonify):
id = Column(Integer, primary_key=True, autoincrement=True)
members = relationship('User', secondary=course_members, backref=backref('courses', lazy='dynamic'))
roles = relationship('Role', secondary=course_roles, backref=backref('roles', lazy='dynamic'))
class Role(Base):
id = Column(Integer, primary_key=True, autoincrement=True)
role_id = Column(Integer, nullable=False)
user_id = Column(Integer, ForeignKey('users.id'))
user = relationship('User', backref=backref("roles", lazy='dynamic'))
UniqueConstraint('role_id', 'user_id', name='role_combination')
有用户查询:
print(type(user.roles))
print(user.roles.filter_by(id=1).first())
# print(user.courses.first() <-- Works fine too.
<class 'sqlalchemy.orm.dynamic.AppenderQuery'>
{id: 1, 'user_id': 1, role_id: 3}
但是对于课程查询:
print(type(course.roles))
print(course.roles.filter_by(id=1).first())
<class 'sqlalchemy.orm.collections.InstrumentedList'>
AttributeError: 'InstrumentedList' object has no attribute 'filter_by'
我尝试使用成员时结果相同。
使用会员和课程作为工作的列表对象:
course.roles[0].user.first()
但是我真的很想念 AppenderQuery class 用于我的课程查询的功能。
这是正常行为还是我遗漏了什么?
在撰写问题和进行研究时,我在 post add dynamic to the other side.
中找到了问题的答案看到答案后,我对关系功能也有了更多了解。
members = relationship('User', secondary=course_members, lazy='dynamic', backref=backref('courses', lazy='dynamic'))
roles = relationship('Role', secondary=course_roles, lazy='dynamic', backref=backref('roles', lazy='dynamic'))
成员和角色关系是父 class 的功能,backref=* 是子 class 的关系功能。我花了比我喜欢的更多的时间来意识到这一点。但是通过将 lazy='dynamic' 作为关系函数中的参数,以及 backref 参数的 backref 函数有效地将其应用于关系的双方。
现在用户、课程和角色作为 AppenderQuery 返回。
希望这能帮助其他人寻找问题。