如何在SQLAlchemy中的子类中定义基类和表名中的表列?

时间:2014-07-02 15:29:20

标签: python mysql sqlalchemy

我需要有两个具有相同结构的独立表,这看起来像一个继承场景,但我不希望基类与表关联。仅存在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.

建议?

1 个答案:

答案 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,您需要在status1status2中定义一个将它们链接在一起的外键:

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__)