在没有外键的情况下在 SQLalchemy ORM 中指定连接条件
Specify join condition in SQLalchemy ORM without foreign key
我在 SQLAlchemy 中有两个模型,我已自动加入外键,如下所示:
class Parent(Base):
__tablename__ = 'parents'
id = Column(Integer, primary_key=True)
name = Column(String(300), nullable=False)
metadata_id = Column(Integer, nullable=True, index=True)
class Child(Base):
__tablename__ = 'children'
id = Column(Integer, primary_key=True)
name = Column(String(300), nullable=False)
parent_metadata_id = \
Column(ForeignKey('parents.metadata_id'),
nullable=True, primary_key=True)
parent = relationship(u'Parent')
这很好用,我可以很容易地从 children 访问 parent。现在,出于超出此问题范围的技术原因,我不得不删除数据库中的外键。我试图在 SQLAlchemy 中解决这个问题,但是 none 的替换代码(使用 primaryjoins 或 backrefs)起作用了。我看到另一个答案 here 只是说对 SQLAlchemy 撒谎并告诉它我有外键关系,但这使得 Alembic 尝试在我自动生成的每个新修订版上创建外键关系,这真的很烦人。正确的做法是什么?
要使 relationship
起作用,您可以指定显式连接条件:
parent = relationship(Parent, primaryjoin=parent_metadata_id == Parent.metadata_id)
要连接到 Child
,您可以指定关系而不是实体:
session.query(Child).join(Child.parent)
或者,明确指定连接条件:
session.query(Child).join(Child, Child.parent_metadata_id == Parent.metadata_id)
对 SQLAlchemy 说谎也有效。您可以通过指定 include_object
参数使 alembic 忽略外键:
class Child(Base):
...
parent_metadata_id = Column(ForeignKey( ... ), info={"skip_autogenerate": True}, ...)
def include_object(object, name, type_, reflected, compare_to):
if not reflected and object.info.get("skip_autogenerate", False):
return False
return True
我在 SQLAlchemy 中有两个模型,我已自动加入外键,如下所示:
class Parent(Base):
__tablename__ = 'parents'
id = Column(Integer, primary_key=True)
name = Column(String(300), nullable=False)
metadata_id = Column(Integer, nullable=True, index=True)
class Child(Base):
__tablename__ = 'children'
id = Column(Integer, primary_key=True)
name = Column(String(300), nullable=False)
parent_metadata_id = \
Column(ForeignKey('parents.metadata_id'),
nullable=True, primary_key=True)
parent = relationship(u'Parent')
这很好用,我可以很容易地从 children 访问 parent。现在,出于超出此问题范围的技术原因,我不得不删除数据库中的外键。我试图在 SQLAlchemy 中解决这个问题,但是 none 的替换代码(使用 primaryjoins 或 backrefs)起作用了。我看到另一个答案 here 只是说对 SQLAlchemy 撒谎并告诉它我有外键关系,但这使得 Alembic 尝试在我自动生成的每个新修订版上创建外键关系,这真的很烦人。正确的做法是什么?
要使 relationship
起作用,您可以指定显式连接条件:
parent = relationship(Parent, primaryjoin=parent_metadata_id == Parent.metadata_id)
要连接到 Child
,您可以指定关系而不是实体:
session.query(Child).join(Child.parent)
或者,明确指定连接条件:
session.query(Child).join(Child, Child.parent_metadata_id == Parent.metadata_id)
对 SQLAlchemy 说谎也有效。您可以通过指定 include_object
参数使 alembic 忽略外键:
class Child(Base):
...
parent_metadata_id = Column(ForeignKey( ... ), info={"skip_autogenerate": True}, ...)
def include_object(object, name, type_, reflected, compare_to):
if not reflected and object.info.get("skip_autogenerate", False):
return False
return True