postgresql 我如何在SQLAlchemy中反向填充多个外键?

7lrncoxx  于 2023-06-29  发布在  PostgreSQL
关注(0)|答案(1)|浏览(131)

这些是我拥有的反射数据库类,资源和游戏:

Base = declarative_base()
Base.metadata.bind = Engine

class ResourceDB(Base):
    __tablename__ = 'resources'
    __table_args__ = {'autoload': True, 'extend_existing': True}
    resource_id = Column('resource_id', Integer, primary_key=True)
    primaryKey = 'resource_id'

class GameDB(Base):
    __tablename__ = 'games'
    __table_args__ = {'autoload': True, 'extend_existing': True}
    game_id = Column('game_id', Integer, primary_key=True)
    primaryKey = 'game_id'
    resource_egm_id = Column(Integer, ForeignKey("resources.resource_id"))
    resource_vm_id = Column(Integer, ForeignKey("resources.resource_id"))

    resourceEgmId = relationship("ResourceDB", foreign_keys=[resource_egm_id], lazy="joined", join_depth=1)
    resourceVmId = relationship("ResourceDB", foreign_keys=[resource_vm_id], lazy="joined", join_depth=1)

从Game对象中,我可以很好地引用2个Resource对象。
然而,我想做的是引用所有连接到资源的游戏。因为,可能有许多游戏(超过2个)使用相同的资源。resources表没有game_id列
我试着用back_populates来交换。

# in ResourceDB
games = relationship("GameDB", back_populates="allResources", foreign_keys="[GameDB.resource_egm_id, GameDB.resource_vm_id]")
# in GameDB, replace the 2 relationships with
allResources = relationship("ResourceDB", back_populates="games", foreign_keys=[resource_egm_id, resource_vm_id])

导致
无法确定关系www.example.com上父/子表之间的联接条件ResourceDB.games-有多个外键路径链接这些表。指定'foreign_keys'参数,提供应被视为包含对父表的外键引用的列的列表。
如果我将ResourceDB中的关系更改为使用表名games

games = relationship("GameDB", back_populates="Resources", foreign_keys="[games.resource_egm_id, games.resource_vm_id]")

我得到了这个:
一个或多个Map程序初始化失败-无法继续初始化其他Map程序。触发Map器:'mapped class ResourceDB-> resources'。最初的例外是:“Table”对象没有属性“resource_egm_id”

  • 取得了一些进展。如果我只有GameDB中的关系并使用backref,我可以获得资源的数据,但由于我使用会话的上下文管理器,我无法获得游戏中的数据。
resourceEgmId = relationship("ResourceDB", foreign_keys=[resource_egm_id], backref="gamesEgm", lazy="joined", join_depth=2)
resourceVmId = relationship("ResourceDB", foreign_keys=[resource_vm_id], backref="gamesVm",lazy="joined", join_depth=2)

父示例未绑定到Session;属性“gamesEgm”延迟加载操作无法继续(此错误的背景位于:https://sqlalche.me/e/14/bhk3)我以前通过将lazy参数设置为joined解决了这个问题,但在ResourceDB类中使用backref时不能这样做。
使用postgresql,python 3.7,sqlalchemy 1.4.45

yrefmtwq

yrefmtwq1#

想明白了我必须创建一个backref对象,你定义的参数的关系引用的对象。
我的最终解决方案:

from sqlalchemy.orm import declarative_base, relationship, sessionmaker, backref

Base = declarative_base()
Base.metadata.bind = Engine

class ResourceDB(Base):
    __tablename__ = 'resources'
    __table_args__ = {'autoload': True, 'extend_existing': True}
    resource_id = Column('resource_id', Integer, primary_key=True)
    primaryKey = 'resource_id'

class GameDB(Base):
    __tablename__ = 'games'
    __table_args__ = {'autoload': True, 'extend_existing': True}
    game_id = Column('game_id', Integer, primary_key=True)
    primaryKey = 'game_id'
    resource_egm_id = Column(Integer, ForeignKey("resources.resource_id"))
    resource_vm_id = Column(Integer, ForeignKey("resources.resource_id"))

    resourceEgmId = relationship("ResourceDB", foreign_keys=[resource_egm_id], 
                                 lazy="joined", join_depth=1, 
                                 backref=backref("gamesEgm", lazy="joined"))
    resourceVmId = relationship("ResourceDB", foreign_keys=[resource_vm_id], 
                                lazy="joined", join_depth=1,
                                backref=backref("gamesVm", lazy="joined"))

https://docs.sqlalchemy.org/en/14/orm/backref.html#specifying-backref-argumentshttps://docs.sqlalchemy.org/en/14/orm/relationship_api.html#sqlalchemy.orm.backref

相关问题