Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/344.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何使用SQLAlchemy设置具有关联对象的邻接列表?_Python_Orm_Sqlalchemy_Adjacency List - Fatal编程技术网

Python 如何使用SQLAlchemy设置具有关联对象的邻接列表?

Python 如何使用SQLAlchemy设置具有关联对象的邻接列表?,python,orm,sqlalchemy,adjacency-list,Python,Orm,Sqlalchemy,Adjacency List,我正在尝试创建一个数据库模型,在这个模型中,您可以拥有一组产品,这些产品可以是其他产品的一部分,也可以包含其他产品。我已经想出了这样做的方法: product_to_product = Table( "product_to_product", Base.metadata, Column("id", Integer, primary_key=True), Column("parent_id", Intege

我正在尝试创建一个数据库模型,在这个模型中,您可以拥有一组产品,这些产品可以是其他产品的一部分,也可以包含其他产品。我已经想出了这样做的方法:

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"),
    )
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]
这让我可以添加如下产品:

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"),
    )
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]
然后,我可以抓取所有的产品,父母/孩子之间的链接完全按照我的意愿工作

现在,我想转而使用关联对象来管理链接,因为我希望有更多的数据。我尝试过这样设置:

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"),
    )
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]
我发现了许多这样做的例子,如果通过多对多关系链接在一起的对象是两个不同的对象(如
User
Community
),但在这种情况下,它是同一个对象。我的尝试是从不同的示例中拼凑而成的,但它与以前的脚本不兼容。我也看到过一些例子使用了
association\u proxy
函数和其他几种方法,但我无法实现这一点


我的目标是能够像以前一样添加产品、链接产品和导航产品,还能够从
产品
访问
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"
    )
其工作原理如下:

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"),
    )
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]
它允许我访问父/子对象,以及引用对象和其中的额外数据