簡體   English   中英

如何正確創建一個與多個外鍵有多對多關系的方塊sqlalchemy

[英]How do I correctly create a flask sqlalchemy many to many relationship with multiple foreign keys

在Flask sqlalchemy文檔中,給出了使用簡單的多對多關系的示例:

tags = db.Table('tags',
    db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
    db.Column('page_id', db.Integer, db.ForeignKey('page.id'))
)

class Page(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    tags = db.relationship('Tag', secondary=tags,
        backref=db.backref('pages', lazy='dynamic'))

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)

可以使用以下語法來聯系相關對象:

Page.tags

我想要完成的是基本上將下面的關系添加到上面的那個:

tag_children = db.Table('tag_children,',
                        db.Column('parent_id', db.Integer, db.ForeignKey('tags.tag_id')),
                        db.Column('child_id', db.Integer, db.ForeignKey('tags.tag_id'))
                        )

這樣每個頁面都附有標簽,但每個標簽在該頁面的范圍內可以有多個子標簽。 我已經為一個名為car的頁面制作了一個展示案例,其中我有它的標簽和各自的子標簽。

(頁)汽車:

  • 奔馳
    • 一系列
    • B系列
    • C系列
  • 特斯拉
    • 特斯拉跑車
    • 型號X.
    • 楷模
    • 模型3

上面的所有列表項都是標記對象

我希望能夠使用以下語法來獲取相關對象:

Page.tag.children

例如(下面的虛擬代碼,但我想明確關系的預期目的是什么):

Cars.tesla.children

我想,你不需要另一個tag_children表。 嘗試使用SQLAlchemy Adjacency列表:

class Tag(db.Model):
    id = db.Column(db.Integer, primary_key=True)
    parent_id = Column(Integer, ForeignKey('tag.id'))
    children = relationship("Tag",
                backref=backref('parent', remote_side=[id])
            )

使用此架構,您可以使用以下語法:

for tag in page.tags:  # where page is a Page instance received from db
    print tag.children

這是使用SQLAlchemy模型的常用語法。 嘗試使用它而不是建議的Cars.tesla.children

Cars['tesla'].children這樣的東西Cars['tesla'].children可以通過getitem方法實現,但我想,這是非常不清楚的方式。

完整代碼段:

class Page(Base):

    __tablename__ = 'page'

    id = Column(Integer, primary_key=True)
    name = Column(String(256))
    tags = relationship('Tag', secondary='tags',
        backref=backref('pages', lazy='dynamic'))

    def __str__(self):
        return self.name


class Tag(Base):

    __tablename__ = 'tag'

    id = Column(Integer, primary_key=True)
    name = Column(String(256))
    parent_id = Column(Integer, ForeignKey('tag.id'))
    children = relationship(
        "Tag",
        backref=backref('parent', remote_side=[id])
    )

    def __str__(self):
        return self.name

class Tags(Base):
    __tablename__ = 'tags'

    tag_id = Column(Integer, ForeignKey('tag.id'), primary_key=True)
    page_id = Column(Integer, ForeignKey('page.id'), primary_key=True)

和測試用例:

# Create page and tags
session.add(Page(id=1, name="cars"))
session.add(Tag(id=1, name="Mercedes"))
session.add(Tag(id=2, name="A-series", parent_id=1))
session.add(Tag(id=3, name="B-series", parent_id=1))
session.add(Tag(id=4, name="C-series", parent_id=1))
session.add(Tag(id=5, name="Tesla"))
session.add(Tag(id=6, name="Tesla Roadster", parent_id=5))
session.add(Tag(id=7, name="Model X", parent_id=5))
session.add(Tag(id=8, name="Model S", parent_id=5))
session.add(Tag(id=9, name="Model 3", parent_id=5))

# Fill relation
session.add(Tags(tag_id=1, page_id=1))
session.add(Tags(tag_id=5, page_id=1))

session.commit()

print session.query(Page).get(1)  # >>> cars
print session.query(Page).get(1).tags  # >>> Mercedes, Tesla
print session.query(Page).get(1).tags[1].children  # >>> Tesla models

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM