2017-09-05 50 views
0

我想動態創建兩個表之間的1:n關係。我的數據庫模型通過SQLAlchemy映射,但由於我的應用程序的一些特殊功能,我無法使用默認的聲明方式。SQLAlchemy:如何以編程方式創建關係

E.g.

class Foo(Base): 
    id = Column(Integer, autoincrement=True, primary_key=True) 
    flag = Column(Boolean) 

class Bar(Base): 
    id = Column(Integer, autoincrement=True, primary_key=True) 
    foo_id = Column(Integer, ForeignKey('foo.id')) 
    # declarative version: 
    # foo = relationship(Foo) 

所以我想定義酒吧後,名爲「foo」的關係添加到映射的類「BAR」 和SQLAlchemy的定義做了一個映射器等。它的工作

更新2017-09 -05:爲什麼這對我有必要? (我認爲我可以省略這個,因爲我認爲它主要是分散實際問題來解決,但因爲有評論關於它...)

首先,我沒有一個單一的數據庫,但數百/數千。舊數據庫中的數據不得以任何方式更改,但我希望單個源代碼訪問舊數據(即使數據結構和計算規則發生顯着變化)。

當前我們使用多個模型定義。後來的定義擴展/修改了以前的定義我們經常動態地操作SQLAlchemy模型。我們儘量不要在映射類中使用代碼,因爲我們認爲在更改表多次之後(代碼必須在每個中間步驟中工作),確保代碼的正確性會困難得多。

在許多情況下,我們在模型X中以編程方式擴展表(映射類),之後它在模型X-1中最初定義。將列添加到現有的SQLAlchemy ORM類是可管理的。現在我們添加一個新的參考列和一個現有的表,relationship()提供了一個更好的Python API。

+0

背後的原因是什麼?你想在創建多重關係時使用外部模型列表嗎? – krassowski

+0

然後,只需爲該課程添加關係屬性,儘管@ krassowski是正確的:您爲什麼需要它? –

+0

@ ilja-everilä:你能詳細說明一下嗎?我需要將關係定義與實際聲明完全分離。基本上我想知道如何操作SQLAlchemy的內部,但我找不到(非常好)文檔中的正確部分,我希望有人可以節省我幾個小時的時間閱讀SQLAlchemy源代碼... :-) –

回答

0

好了,我上面的問題又是SQLAlchemy的的超能力(和我有限的瞭解)一個很好的例子:

Bar.__mapper__.add_property('foo', relationship('Foo')) 

很有可能我無法最初得到這個工作,因爲我的一些周圍的代碼混合添加關係和列。也有是宣告列一個重要的區別:

Column('foo', Integer) 

列的第一個參數可以是列名,但你不能用這個關係。 relationship('foo', 'Foo')傳遞給.add_property()時觸發異常。