带有过滤器

时间:2016-09-09 09:37:50

标签: python postgresql flask sqlalchemy flask-admin

我在PostgreSQL中有一个表,其中包含有关文档的信息。让我们这样说:

table: doc

id (int)
name (string)
type (int)

类型是文档的类别(例如1 - 护照,2 - 保险等)。此外,我还有不同的表格,其中包含每种docyment类型的附加信息。

table: info

id (int)
doc_id (fk)
info (additional columns)

我希望有一个SQLAlchemy模型来处理与其链接的每种类型的文档的附加信息,并能够管理要显示的列(对于Flask-Admin,如果它很重要)。

现在将两个表加入某种"模型"我使用SQLAlchemy文档中的Mapping Table Columns(当只有一种类型的文档时):

class DocMapping(db.Model):

    __table__ = doc.__table__.join(info)
    __mapper_args__ = {
        'primary_key': [doc.__table__.c.id]
    }

现在的问题是:如何基于doc.type列创建从db.Model(DocPassportMapping,DocInsuranceMapping等)继承的多个类?

类似的东西:

__table__ = doc.__table__.join(info).filter(doc.type)

这显然不起作用,因为我们在这里没有查询对象。

1 个答案:

答案 0 :(得分:3)

如果我理解正确,您希望inheritance hierarchy基于DocMappingDocMapping.type作为多态身份。由于您还没有提供完整的示例,因此这里的结构有点类似。它确实存在差异,但应适用于您的。这会在联接映射之上使用single table inheritance

模特:

In [2]: class Doc(Base):
   ...:     id = Column(Integer, primary_key=True, autoincrement=True)
   ...:     name = Column(Unicode)
   ...:     type = Column(Integer, nullable=False)
   ...:     __tablename__ = 'doc'
   ...:     

In [3]: class Info(Base):
   ...:     __tablename__ = 'info'
   ...:     doc_id = Column(Integer, ForeignKey('doc.id'), primary_key=True)
   ...:     value = Column(Unicode)
   ...:     doc = relationship('Doc', backref=backref('info', uselist=False))
   ...:     

In [4]: class DocMapping(Base):
   ...:     __table__ = Doc.__table__.join(Info)
   ...:     __mapper_args__ = {
   ...:         'primary_key': (Doc.id, ),
   ...:         # These declare this mapping polymorphic
   ...:         'polymorphic_on': Doc.type,
   ...:         'polymorphic_identity': 0,
   ...:     }
   ...:     

In [5]: class Passport(DocMapping):
   ...:     __mapper_args__ = {
   ...:         'polymorphic_identity': 1,
   ...:     }
   ...:     

In [6]: class Insurance(DocMapping):
   ...:     __mapper_args__ = {
   ...:         'polymorphic_identity': 2,
   ...:     }
   ...:     

测试:

In [7]: session.add(Insurance(name='Huono vakuutus',
   ...:                       value='0-vakuutus, mitään ei kata'))

In [8]: session.commit()

In [15]: session.query(DocMapping).all()
Out[15]: [<__main__.Insurance at 0x7fdc0a086400>]

In [16]: _[0].name, _[0].value
Out[16]: ('Huono vakuutus', '0-vakuutus, mitään ei kata')

问题是:您可能不希望从db.Model继承的多个类作为基础,而是从DocMapping继承的类。作为一个层次结构,它更有意义。