我需要有两个具有相同结构的独立表,这看起来像一个继承场景,但我不希望基类与表关联。仅存在Base
以定义子类中的表的列。 The AbstractConcreteBase
docs让我以这种方式实施:
status.py
中的:
class Base(AbstractConcreteBase):
id = Column('id', Integer, primary_key=True)
date = Column('date', DateTime(), nullable=False)
class Status1(Base):
__tablename__ = 'status1'
__mapper_args__ = {
'polymorphic_identity': __tablename__,
'concrete': True
}
class Status2(Base):
__tablename__ = 'status2'
__mapper_args__ = {
'polymorphic_identity': __tablename__,
'concrete': True
}
part.py
中的:
class Part(declarative_base()):
__tablename__ = 'parts'
id = Column('id', Integer, primary_key=True)
status1 = relationship('Status1', uselist=True, backref=backref('status1', order_by='Status1.date'))
status2 = relationship('Status2', uselist=True, backref=backref('status2', order_by='Status2.date'))
尝试此操作时,出现以下错误:
InvalidRequestError: When initializing mapper Mapper|Part|parts, expression 'Status1' failed to locate a name ("name 'Status1' is not defined"). If this is a class name, consider adding this relationship() to the <class 'package.Part'> class after both dependent classes have been defined.
建议?
答案 0 :(得分:2)
你真正想要的是一个Mixin课程。如果不希望将基类与表关联,则基类不应继承SQLAlchemy declarative_base
。 mixin将根据您的需要定义列/表结构。您的子课程继承自两者 mixin和declarative_base
。
mixin定义如下:
class StatusMixin(object):
id = Column('id', Integer, primary_key=True)
date = Column('date', DateTime(), nullable=False)
子类变得更简单:
Base = declarative_base()
class Status1(StatusMixin, Base):
__tablename__ = 'status1'
class Status2(StatusMixin, Base):
__tablename__ = 'status2'
最后,未正确定义为relationship
类定义的Part
。要使用backref
,您需要在status1
和status2
中定义一个将它们链接在一起的外键:
class Status1(StatusMixin, Base):
__tablename__ = 'status1'
part_id = Column('part_id', Integer, ForeignKey('parts.id'))
定义relationship
backref
的表格需要将backref
作为child1
,而不是child2
和{{1}的名称} tables:
class Part(declarative_base()):
__tablename__ = 'parts'
id = Column('id', Integer, primary_key=True)
status1 = relationship('Status1', uselist=True, backref=__tablename__)
status2 = relationship('Status2', uselist=True, backref=__tablename__)