python - SQLAlchemy:具有单表继承的邻接表
问题描述
我正在尝试设置以下单表继承邻接列表结构,其中子对象包含与父对象的关系:
class Parent(Base):
__tablename__ = 'testtable'
type = Column(String)
__mapper_args__ = {
'polymorphic_on':type,
'polymorphic_identity':'Parent'
}
id = Column(Integer, primary_key = True)
class Child(Parent):
__mapper_args__ = {
'polymorphic_identity':'Child'
}
parent_id = Column(Integer, ForeignKey('testtable.id'))
parent = relationship('Parent')
但是,当我尝试创建 Child 类型的对象并设置/附加父对象时:
p = Parent()
c = Child()
c.parent.append(p)
db_session.add(c)
db_session.commit()
我收到以下错误:
UnmappedColumnError:无法为目标列“testtable.parent_id”执行同步规则;mapper 'mapped class Parent->testtable' 不映射此列。尝试使用foreign_keys
不包含此列的显式集合(或使用 viewonly=True 关系)。
我玩弄了不同的关系定义(backref 等),但在这个阶段我很迷茫。任何想法将不胜感激!
非常感谢提前
为方便起见,这里有一个完整的例子:
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import Column, Integer, String
from sqlalchemy import ForeignKey
from sqlalchemy.orm import relationship
Base = declarative_base()
Session = sessionmaker()
engine = create_engine('sqlite:///test.db')
Session.configure(bind = engine)
db_session = Session()
class Parent(Base):
__tablename__ = 'testtable'
type = Column(String)
__mapper_args__ = {
'polymorphic_on':type,
'polymorphic_identity':'Parent'
}
id = Column(Integer, primary_key = True)
class Child(Parent):
__mapper_args__ = {
'polymorphic_identity':'Child'
}
parent_id = Column(Integer, ForeignKey(Parent.id))
parent = relationship('Parent', remote_side=[parent_id])
Base.metadata.create_all(engine)
p = Parent()
c = Child()
c.parent.append(p)
db_session.add(c)
db_session.commit()
解决方案
您的Child
对象有一个外键,Parent
因此它是多对一的关系。因此,您需要使用c.parent = p
而不是c.parent.append(p)
. 您还需要remote_side=Parent.id
使用relationship
.
工作示例:
from sqlalchemy import create_engine, Column, Integer, String, ForeignKey
from sqlalchemy.orm import declarative_base, relationship, Session
Base = declarative_base()
engine = create_engine("sqlite://")
class Parent(Base):
__tablename__ = "testtable"
type = Column(String)
__mapper_args__ = {
"polymorphic_on": type,
"polymorphic_identity": "Parent",
}
id = Column(Integer, primary_key=True)
def __repr__(self):
return f"<Parent(id={self.id})>"
class Child(Parent):
__mapper_args__ = {"polymorphic_identity": "Child"}
parent_id = Column(Integer, ForeignKey(Parent.id))
parent = relationship("Parent", remote_side=Parent.id)
def __repr__(self):
return f"<Child(id={self.id}, parent_id={self.parent_id})>"
Base.metadata.create_all(engine)
with Session(engine) as db_session:
p = Parent()
c = Child()
c.parent = p
db_session.add(c)
db_session.commit()
print(c) # <Child(id=2, parent_id=1)>
推荐阅读
- c# - 实体框架 6 BulkInsert 从客户端 SQL SERVER 2012 Express 接收到无效的列长度
- java - 导航栏打开时 MainActivity 仍然可以点击
- maven - 为多个依赖项指定相同的版本?
- ios - 通过 Codable 协议解析 JSON
- powershell - 将 Skype for Business 与 ChatBot 连接
- reactjs - 使用 Cookie 反应原生
- c++ - 寻找部分代码的解释
- c++ - 在构造函数中将动态分配的数组分配给唯一的智能指针成员变量
- php - Php can't find tidy
- machine-learning - NLP初学者