SQLAlchemy继承基于数据是否存在于另一个表中

时间:2011-10-21 23:04:33

标签: python inheritance sqlalchemy

我有两个遗留表,我想使用SQLAlchemy声明来访问数据。

Order:
order_id
is_processed

FooData:
foo_id
order_id

订单可能有也可能没有FooData,我想使用SQLAlchemy声明模型区分两种订单类型。

我头脑中的问题是。

  • 我如何建立这样的关系?理想情况下,我有两个类Order和FooOrder,其中Order没有FooData,FooOrder有FooData。
  • 我必须根据is_processed一起查询这两种类型(Order和FooOrder),并根据它是Order还是FooOrder对它们进行不同的处理。在这种情况下如何查询?

1 个答案:

答案 0 :(得分:0)

如果您可以更改数据库,则只需添加一个discriminator column,即可 根据是否,此列的值为正确值(order | foodata) foodata存在于其中,使其成为NOT NULL并配置简单的连接表继承。

如果你不能改变数据库(添加一个鉴别器列)而你只有简单 你展示的2表模型,然后我不会使用继承,而是1-1关系。

模型定义:

class Order(Base):
    __tablename__ = 'order'
    __table_args__ = {'autoload': True}

class FooData(Base):
    __tablename__ = 'foo_data'
    __table_args__ = {'autoload': True}
    # @note: you need next line only if your DB does not have FK defined
    #__table_args__ = (ForeignKeyConstraint(['order_id'], ['order.order_id']), {'autoload': True})

# define 1-[0..1] relationship from Order to FooData with eager loading
Order.foodata = relationship(FooData, uselist=False, lazy="joined", backref="order")

添加新对象:

ord = Order(); ord.is_processed = False
session.add(ord)
ord = Order(); ord.is_processed = False
foo = FooData(); foo.someinfo = "test foo created from SA"
ord.foodata = foo
session.add(ord)
session.commit()

查询:全部基于is_processed:

qry = session.query(Order).filter(Order.is_processed == False)
for ord in qry:
    print ord, ord.foodata

A la 多态:

您甚至可以通过某种方式在OrderFooData上实施方法 看起来他们实际上是在使用继承:

class Order(Base):
    # ...
    def process_order(self):
        if self.foodata:
            self.foodata.process_order()
        else:
            print "processing order: ", self

class FooData(Base):
    # ...
    def process_order(self):
        print "processing foo_data: ", self