簡體   English   中英

Python / SqlAlchemy 3向循環依賴

[英]Python/SqlAlchemy 3-way circular dependency

我在3個表之間創建一組關系時遇到問題。 當我運行代碼創建表時,出現循環依賴錯誤。

我嘗試根據對類似帖子的回復來擺弄use_alterpost_update ,但是我無法解決問題。

基本上,地圖具有一組位置,角色具有一組地圖,但是角色也位於那些地圖位置中的一個上。 另外,地圖可以與其他地圖具有父/子關系。

class Character(Base):
    __tablename__ = 'character'

    ID = Column(Integer, primary_key=True)
    name = Column(Unicode(255), nullable=False)
    classID = Column(Integer, nullable=False)
    created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)

    profileID = Column(Integer, ForeignKey('profile.ID'), nullable=False)
    locationID = Column(Integer, ForeignKey('location.ID'))

    location = relationship("Location")
    maps = relationship("Map", backref="owner", cascade="save-update, merge, delete, delete-orphan")

class Map(Base):
    __tablename__ = 'map'

    ID = Column(Integer, primary_key=True)
    name = Column(Unicode(255))
    maptypeID = Column(Integer, nullable=False)
    created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)

    parentID = Column(Integer, ForeignKey('map.ID'))
    ownerID = Column(Integer, ForeignKey('character.ID'))

    children = relationship("Map", backref=backref("parent", remote_side="Map.ID"))
    locations = relationship("Location", backref='map', cascade="save-update, merge, delete, delete-orphan")

class Location(Base):
    __tablename__ = 'location'

    ID = Column(Integer, primary_key=True)
    x = Column(Integer, nullable=False)
    y = Column(Integer, nullable=False)
    locationtypeID = Column(Integer, nullable=False)
    created = Column(DateTime, nullable=False, default=datetime.datetime.utcnow)

    mapID = Column(Integer, ForeignKey('map.ID'), nullable=False)

我該如何解決這個問題?

編輯(已解決):

在更多地使用use_alter ,我可以通過將Location類中的mapID定義從以下更改來解決該問題:

mapID = Column(Integer, ForeignKey('map.ID'), nullable=False)

至:

mapID = Column(Integer, ForeignKey('map.ID', use_alter=True, name="fk_location_map"), nullable=False)

為了響應打破循環依賴性的建議,我寧願在架構中表示正確的關系和數據完整性。 我寧願擔心解決ORM問題或更改ORM,也不願對架構進行修改以使其符合ORM的期望。

在這種特殊情況下,我想不出一種更簡潔,優雅的方式來表示我需要模式來表示應用程序的所有信息 (從最基本的意義上來說)。

旁注:與其他語言/框架/ ORM一起使用后,ORM通常會自動解決這種問題。 例如,在.NET E / F中,我相信通常會在所有表創建語句之后添加並激活FK約束。

您可能會得到Alembic來幫助您解決架構中的循環依賴關系,但我不會為您提供幫助。 相反,我強烈建議您打破循環依賴

如果我了解您的架構,則可以使用Location表示模型中的房間或建築物。 模式中的玩家/怪物是Character ,在任何時候都必須精確地位於一個location 此外,還有一些Map項左右浮動,它總是一些特定的location ,並且總是在只有一個的庫存character

所以這是我的拼寫方式

class Location:
    id = Column(Integer, primary_key=True)

class Character:
    id = Column(Integer, primary_key=True)
    location_id = Column(ForeignKey(Location.id))

    location = relationship(Location, backref="characters")

class Map:
    id = Column(Integer, primary_key=True)
    location_id = Column(ForeignKey(Location.id))
    owner_id = Column(ForeignKey(Character.id))

    location = relationship(Location, backref="maps")
    owner = relationship(Character, backref="inventory")

暫無
暫無

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

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