Python 烧瓶多对多连接由来自django的预取_完成
我有下面的组和接触模型在烧瓶中与Sql炼金术ORMPython 烧瓶多对多连接由来自django的预取_完成,python,postgresql,sqlalchemy,Python,Postgresql,Sqlalchemy,我有下面的组和接触模型在烧瓶中与Sql炼金术ORM group_contact = db.Table( 'group_contact', db.Column('group_id', db.Integer, db.ForeignKey( 'group.id')), db.Column('contact_id', db.Integer, db.ForeignKey( 'contact.id')), db.PrimaryKeyConstr
group_contact = db.Table(
'group_contact',
db.Column('group_id', db.Integer, db.ForeignKey(
'group.id')),
db.Column('contact_id', db.Integer, db.ForeignKey(
'contact.id')),
db.PrimaryKeyConstraint('group_id', 'contact_id')
)
class Group(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(100))
class Contact(db.Model):
id = db.Column(db.Integer, primary_key=True)
phone = db.Column(db.String(15), nullable=False, unique=True)
groups = db.relationship(
"Group", secondary=group_contact, backref='contacts')
现在我需要查询与组的联系:
contacts = Contact.query.join(Group, Contact.groups).all()
for contact in contacts:
print(contact.groups)
这里的问题是,当我执行上述代码时,SQL查询的数量随着联系人数量的增加而增加
Django ORM具有带有queryset的prefetch_related(),它根据Django执行以下操作
另一方面,prefetch_-related对每个关系执行单独的查找,并在Python中执行“连接”。这允许它预取多对多和多对一对象,这是使用select_-related无法完成的,此外,select_-related还支持外键和一对一关系
现在,我尝试通过以下代码对Sql Alchemy执行相同的操作:
contacts = Contact.query.all()
contact_groups = group_contact.query.join(
Group
).filter(group_contact.contact_id.in_([item.id for item in contacts]))
但这给了我一个错误:
AttributeError: 'Table' object has no attribute 'query'
如何使用SqlAlchemy从django获得与预取_相关的功能 您希望告诉SQLAlchemy通过使用。SQLAlchemy可以被告知在一个查询中将组和联系人一起加载 对于这一个查询,您可以添加(可通过Flask SQLAlchemy
db
对象获得):
这将在每个匹配的联系人上预加载Contact.groups
属性:
for contact in contacts:
# no new query issued to fetch groups, the data for the groups
# is already available
print(contact.groups)
执行的查询如下所示:
选择
contact.id作为contact\u id,
contact.phone作为contact_phone,
组\u 1.id作为组\u 1\u id,
组名称作为组名称
从接触
左外连接(
组联系人作为组联系人1
将“group”作为group_1.id=group_contact_1.group_id上的group_1加入
)ON contact.id=组\联系人\ 1.contact\u id
您还可以为模型上的关系设置默认加载策略;要始终急切地加载组,请在关系上使用lazy='joined'
:
class Contact(db.Model):
# ...
groups = db.relationship(
"Group", secondary=group_contact, backref='contacts',
lazy='joined')
谢谢你的回答。这很有帮助。
class Contact(db.Model):
# ...
groups = db.relationship(
"Group", secondary=group_contact, backref='contacts',
lazy='joined')