2011-09-14 48 views
0

我使用SQLAlchemy,但不是以聲明方式,我本質上是試圖使用由SOAP Web服務(動態類)提供的數據填充數據庫。Sqlalchemy ORM表之間的非聲明性鏈接

我遇到的麻煩是在對象的不同部分之間創建映射,因爲這些表在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')) 

我想要做什麼是做了LineItem作爲發票的一部分:

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

但是,這回來了一個錯誤它不知道這兩個對象/表之間的關係(underst因爲沒有外鍵存在)。我一直在嘗試不同的參數(primaryjoin,backref等),但到目前爲止我還沒有成功。

任何幫助將不勝感激,我知道這可能不是最好的方式來做到這一點,但這個特定的腳本是數據驅動的,並且需要在SOAP服務發生變化時有些動態。

編輯: shahjapan對primaryjoin參數的建議有幫助,但我現在得到一個錯誤「無法確定primaryjoin條件的關係方向」,所以我認爲我們走在正確的軌道上,只是還沒有。

回答

4

只要給在孩子外鍵,它會authomaticaly工作。

LineItme

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

不工作,我相信只有在使用聲明性表單時纔有效。 – David

+0

@David:它屬於表聲明,不屬於類體;這樣做更有意義嗎? – SingleNegationElimination

+1

完美的作品! – David

1

嘗試使用relation API的PrimaryJoin關鍵字阿根廷,

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

四處錯誤「基於列的表達式預期參數對象」我要去嘗試與表對象打轉轉,看看我是否能得到答案。 – David

+0

好的,改變了primaryjoin = InvoiceTbl.c.id .__ eq __(LineItemTbl.c.refid),現在我得到'無法確定primaryjoin條件的關係方向'。我想我越來越近,如果現在所有抱怨的是方向。 – David

+0

剛剛複製了表並從MyISAM轉換到InnoDB並向表中添加了一個外鍵。添加表達式(InvoiceTbl.c.InvoiceNumber == LineItemTbl.c.InvoiceNumber)現在可用。有關我如何放棄這種需求的想法? – David