Pat*_*Yan 9 python sqlalchemy flask-sqlalchemy
我有四个类,像这样:Group,Parent,Child,Toy.
Group有一种parents关系指向ParentParent有一种children关系指向ChildChild有一种toys关系指向ToyParent有一个toys association_proxy产生所有Toy的S Parent的孩子们.
我希望能够获得一组中的所有玩具.我试图创建一个association_proxy对Group链接到Parent的toys,但它会产生这样的:
[[<Toy 1>, <Toy 2>], [], [], []]
Run Code Online (Sandbox Code Playgroud)
当我想要这个:
[<Toy 1>, <Toy 2>]
Run Code Online (Sandbox Code Playgroud)
如果Parent的children没有任何Toys,则toys关联代理[].但是,第二个关联代理不知道要排除空列表.此外,列表应折叠.反正有没有让这个工作?
class Group(db.Model):
id = db.Column(db.Integer, primary_key=True)
created_at = db.Column(db.DateTime, default=utils.get_now_datetime)
name = db.Column(db.String(80, convert_unicode=True))
# relationships
parents = db.relationship('Parent', backref='group')
toys = association_proxy('parents', 'toys')
class Parent(db.Model):
id = db.Column(db.Integer, primary_key=True)
group_id = db.Column(db.Integer, db.ForeignKey('group.id', ondelete='CASCADE'))
created_at = db.Column(db.DateTime, default=utils.get_now_datetime)
first_name = db.Column(db.String(80, convert_unicode=True))
last_name = db.Column(db.String(80, convert_unicode=True))
children = db.relationship('Child', backref='parent', cascade='all, delete')
toys = association_proxy('children', 'toys')
class Child(db.Model):
id = db.Column(db.Integer, primary_key=True)
parent_id = db.Column(db.Integer, db.ForeignKey('parent.id', ondelete='CASCADE'))
created_at = db.Column(db.DateTime, default=utils.get_now_datetime)
class Toy(db.Model):
id = db.Column(db.Integer, primary_key=True)
child_id = db.Column(db.Integer, db.ForeignKey('child.id', ondelete='CASCADE'))
created_at = db.Column(db.DateTime, default=utils.get_now_datetime)
child = db.relationship('Child', backref=db.backref("toys",cascade="all, delete-orphan", order_by="desc(Toy.id)"))
Run Code Online (Sandbox Code Playgroud)
鉴于这些是检索和仅查看(如你在评论中提到,将是不明确的),我宁愿做一个viewonly关系没有的association_proxy:
class Group(db.Model):
# ...
toys = relationship('Toy',
secondary="join(Group, Parent, Group.id == Parent.group_id).join(Child, Parent.id == Child.parent_id)",
primaryjoin="and_(Group.id == Parent.group_id, Parent.id == Child.parent_id)",
secondaryjoin="Child.id == Toy.child_id",
viewonly=True,
)
Run Code Online (Sandbox Code Playgroud)
请注意,这是SQLAlchemy的新功能Composite “Secondary” Joins,在文档的部分中进行了描述。
然后,您可以将其仅用于查询:
group_id = 123
group = session.query(Group).get(group_id)
print(group.toys)
Run Code Online (Sandbox Code Playgroud)
或者甚至可以使用它进行过滤,因此要查找包含名称为“ Super Mario”的玩具的组,可以执行以下操作:
group = session.query(Group).filter(Group.toys.any(Toy.name == "Super Mario"))
Run Code Online (Sandbox Code Playgroud)
但实际上,您可以使用简单查询或创建启用查询的属性来完成所有这些操作。请参阅文档的“ 自定义列属性”部分,您可以在其中使用任何简单属性column_property或hybrid attribute。
| 归档时间: |
|
| 查看次数: |
1420 次 |
| 最近记录: |