[英]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.