[英]How do I set up a adjacency list with an association object with SQLAlchemy?
我正在嘗試創建一個數據庫模型,您可以在其中擁有一堆產品,這些產品可能是其他產品的一部分,也包含其他產品。 我已經想出了如何做到這一點:
product_to_product = Table(
"product_to_product",
Base.metadata,
Column("id", Integer, primary_key=True),
Column("parent_id", Integer, ForeignKey("products.id")),
Column("child_id", Integer, ForeignKey("products.id")),
)
class Product(Base):
__tablename__ = "products"
id = Column(Integer, primary_key=True)
parents = relationship(
"Product",
secondary=product_to_product,
primaryjoin=id == product_to_product.c.parent_id,
secondaryjoin=id == product_to_product.c.child_id,
backref="children",
)
這讓我可以添加這樣的產品:
root = Product()
parent1 = Product()
parent2 = Product()
child1 = Product()
child2 = Product()
child3 = Product()
root.children = [parent1, parent2]
parent1.children = [child1, child2, child3]
parent2.children = [child1, child2]
然后我可以獲取所有產品,並且父母/孩子之間的鏈接完全按照我的意願工作。
現在我想改用關聯對象來管理鏈接,因為我想要額外的數據。 我試過這樣設置:
class ParentReference(Base):
__tablename__ = "parent_references"
id = Column(Integer, primary_key=True)
parent_id = Column(Integer, ForeignKey("products.id"))
child_id = Column(Integer, ForeignKey("products.id"))
additional_data = Column(String)
class Product(Base):
__tablename__ = "products"
id = Column(Integer, primary_key=True)
parents = relationship(
"Product",
secondary=ParentReference,
primaryjoin=id == ParentReference.child_id,
secondaryjoin=id == ParentReference.parent_id,
backref=backref("children"),
)
如果通過多對多關系鏈接在一起的對象是兩個不同的對象(如User
和Community
),我發現了很多例子,但從來沒有在這種情況下它是同一個對象。 我的嘗試是從不同的例子拼湊起來的,但它不像以前那樣與腳本一起工作。 我還看到過使用association_proxy
函數和其他幾種方法的示例,但我無法使其正常工作。
我的目標是能夠像以前一樣添加產品、鏈接它們並導航它們,而且還能夠從Product
訪問ParentReference
對象,以便我可以獲取關於它的附加數據。 有人可以幫我解決這個問題嗎?
經過更多的反復試驗,我想出了如何做到這一點。 這是我的解決方案:
class ParentReference(Base):
__tablename__ = "parent_references"
parent_id = Column(Integer, ForeignKey("products.id"), primary_key=True)
child_id = Column(Integer, ForeignKey("products.id"), primary_key=True)
extra_data = Column(String)
parent = relationship(
"Product",
primaryjoin=lambda: ParentReference.child_id == Product.id,
backref="child_references"
)
child = relationship(
"Product",
primaryjoin=lambda: ParentReference.parent_id == Product.id,
backref="parent_references"
)
class Product(Base):
__tablename__ = "products"
id = Column(Integer, primary_key=True)
parents = relationship(
"Product",
secondary="parent_references",
primaryjoin=lambda: Product.id == ParentReference.parent_id,
secondaryjoin=lambda: Product.id == ParentReference.child_id,
backref="children"
)
這像這樣工作:
root = Product()
parent1 = Product()
parent2 = Product()
child1 = Product()
child2 = Product()
child3 = Product()
parent1.parent_references = [
ParentReference(parent=root, child=parent1, extra_data="Hello World!")
]
root.children.append(parent2)
parent1.children = [child1, child2, child3]
parent2.children = [child1, child2]
它允許我訪問父母/孩子,以及參考對象和其中的額外數據。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.