Sqlalchemy ORM表之间的非声明性链接

时间:2011-09-14 15:18:03

标签: orm mapping sqlalchemy

我使用SQLAlchemy但不是以声明方式使用,我本质上是尝试使用由SOAP Web服务(动态类)提供的数据来填充数据库。

我遇到的问题是在对象的不同部分之间创建映射,由于这些表位于没有外键支持的MySQL的MyISAM表上,因此更加困难。

import sqlalchemy

dbE = sqlalchemy.create_engine('create string')
dbM = sqlalchemy.MetaData()
dbM.bind = dbE

class Invoice(object):
    pass

class LineItem(object):
    pass

InvoiceTbl = sqlalchemy.Table('Invoices', dbM, autoload = True)
LineItemTbl = sqlalchemy.Table('Invoices_Items', dbM, autoload = True)

LineItemMapper = orm.mapper(InvoiceLineItemTbl, InvoiceLineItemTbl)
InvoiceMapper = orm.mapper(Invoice, InvoiceTbl)

sm = orm.sessionmaker(bind = dbE, autoflush = True, autocommit = False, 
                      expire_on_commit = True)
session = orm.scoped_session(sm)

使用上面我可以分别用以下内容查询发票的不同部分,对象将填充匹配表中的列:

invoiceData = session.query(Invoice).filter(Invoice.InvoiceNumber.like('12345'))
invoiceItems = session.query(LineItem).filter(LineItem.InvoiceNumber.like('12345'))

我想要做的是将LineItems作为发票的一部分:

orm.mapper(Invoice, InvoiceTbl properties={
    'LineItems' : orm.relation(LineItem),
    })

但是这回来时有一个错误,它不知道两个对象/表之间的关系(可以理解,因为没有外键存在)。我一直在尝试不同的参数(primaryjoin,backref等),但到目前为止我还没有成功。

任何帮助都会受到赞赏,我知道这可能不是最好的方法,但是这个特定的脚本是数据驱动的,并且在SOAP服务发生变化时需要有点动态。

编辑: shahjapan对primaryjoin参数的建议有所帮助,但我现在收到一个错误“无法确定关于primaryjoin条件的关系方向”,所以我假设我们是在正确的轨道上,只是还没有。

2 个答案:

答案 0 :(得分:4)

只要在孩子身上给外键,它就会起作用。

LineItme

LineItemTbl = sqlalchemy.Table('Invoices_Items', dbM,
    Column(InvoiceNumber, ForeignKey('InvoiceTbl.InvoiceNumber),
    autoload = True)

答案 1 :(得分:1)

尝试使用PrimaryJoin API的relation关键字arg,

orm.mapper(Invoice, InvoiceTbl properties={
    'LineItems' : orm.relation(LineItem,
                  primaryjoin='Table1.id==Table2.refid'),
    })