我遇到了在我的3个表中创建一组关系的问题。当我运行代码来创建表时,我得到循环依赖性错误。
我根据对类似帖子的回复尝试摆弄use_alter
和post_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约束。
答案 0 :(得分:0)
您可以使用alembic来帮助您在架构中使用循环依赖,但我不会帮助您。相反,我强烈要求你打破循环依赖。
如果我了解您的架构,您的模型中的房间或建筑物由Location
代表。您的架构中的玩家/怪物是Character
s,它们在任何时候都必须只有一个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")