[英]SQLAlchemy User Many to Many Relationship
我正在研究一个用户结构,其中用户可以拥有由用户对象组成的父母和孩子。 我一直在尝试让以下内容在 SQLAlchemy 和 Flask 中以多种不同的方式工作。
这是我要如何构建它的示例:
UserTable
id | name
---+-----
1 | Kim
2 | Tammy
3 | John
4 | Casey
5 | Kyle
UserRelationship
id | parent_user_id | child_user_id
---+----------------+---------------
1 | 1 | 2
2 | 1 | 3
3 | 4 | 2
Kim 是 Tammy 和 John 的父母。 凯西是塔米的父母。 塔米是金和凯西的孩子。 约翰是金的孩子。 凯尔没有孩子也没有父母。
我的错误是:
sqlalchemy.exc.AmbiguousForeignKeysError: Could not determine join condition
between parent/child tables on relationship User.parents - there are multiple
foreign key paths linking the tables via secondary table 'user_relationship'.
Specify the 'foreign_keys' argument, providing a list of those columns which
should be counted as containing a foreign key reference from the secondary
table to each of the parent and child tables.
我的model.py
文件如下所示:
user_relationship = db.Table(
'user_relationship',
db.Model.metadata,
db.Column('child_user_id', db.Integer, db.ForeignKey('user.id')),
db.Column('parent_user_id', db.Integer, db.ForeignKey('user.id'))
)
class User(db.Model):
__tablename__ = 'user'
id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)
email = db.Column(db.String(120), unique=True)
pwdhash = db.Column(db.String(54))
parents = relationship('User',
secondary=user_relationship,
backref=db.backref('children'),
cascade="all,delete")
这可能不是处理 Flask 或 SQLAlchemy 中多对多分层用户关系的最佳方式。任何关于如何构建它的见解都会很棒。
谢谢
db.Table
主要用于两个不同实体之间存在Many to Many
关系时。 这里父母和孩子都是User
。
就您而言,下面的代码会很好:
class User(db.Model):
__tablename__ = 'users'
id = db.Column(db.Integer, primary_key=True, unique=True, nullable=False)
email = db.Column(db.String(120), unique=True)
pwdhash = db.Column(db.String(54))
class Parent(db.Model):
__tablename__ = 'parents'
child_id = db.Column(db.Integer, db.Foreignkey('users.id'))
parent_id = db.Column(db.Integer, db.Foreignkey('users.id'))
child = db.relationship('User', foreign_keys=[child_id], backref = 'parents')
flask_sqlalchemy
写在上面SQLAlchemy
,有这个问题的一个很好的阐述在这里 (处理多个连接路径)在SQLAlchemy的网站。
primaryjoin
和secondaryjoin
参数。 最近我遇到了类似的问题,虽然我看到文档和接受的答案建议用户Parent
model 而不是创建关系表,但我创建一个单独的 model 来存储关系是没有意义的,因为我的所有模型都继承自BaseModel
和我不希望这种关系获得BaseModel
的附加功能。 主要是因为我的BaseModel
默认有id
而BaseTable
没有包含id
所以,我更喜欢为关系创建一个单独的 Sqlalchemy 表,而不是 Model。
要完成它,您可以使用primaryjoin
和secondaryjoin
arguments,如下所示。 我与 relationship_manager 之间存在多对一的投资者关系。 要使其成为多对多,您可以从关系表中的investor_id
中删除unique=True
,并从用户 model 中的 relationship_manager 中删除uselist=False
。
# user.py
from database.relationships.relationship_managers import relationship_managers
class User(BaseModel):
id = Column(Integer, primary_key=True)
relationship_manager = relationship(
"User",
secondary=relationship_managers,
uselist=False,
primaryjoin=("relationship_managers.c.investor_id == User.id"),
secondaryjoin=("relationship_managers.c.rel_manager_id == User.id"),
backref="investors"
)
# relationship_managers.py
relationship_managers = BaseTable(
"relationship_managers",
Column("investor_id", Integer, ForeignKey('user.id', ondelete="CASCADE"), unique=True),
Column("rel_manager_id", Integer, ForeignKey('user.id', ondelete="CASCADE")),
)
在这里, primaryjoin
执行第一次与 investor_id 的连接并获取记录用户记录,但这对我们来说还不够。 所以,我们需要secondaryjoin
专门获取 relationship_manager 的 id。
如有任何疑问,请随时发表评论并提出建议。 希望这可以帮助使用 Sqlalchemy 在其项目中同时拥有模型和表格的任何人。:)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.