2013-03-07 110 views
24

我有各種類似(但不完全相同)的數據庫,並希望使用SQLAlchemy作爲「標準化」訪問的一種方式。數據庫可能略有不同,例如在列名上有一個唯一的前綴,或者它們可能會有較大的差異,並且會丟失列(或舊數據庫,缺少整個表)。SQLAlchemy和多個數據庫

我正在尋找的幫助不是一個SQLAlchemy問題,因爲它是一個Python /組織的問題。我如何能夠輕鬆地在項目中重複使用多個數據庫設置?

我讀過關於SQLAlchemy會話,但看不到每種項目都沒有實例化每個項目的方法。

我的問題是這樣的:我怎麼能做一個模塊/包,將包含許多數據庫模型設置SQLAlchemy中使用,可以很容易地導入/在另一個python項目中使用?

我並不擔心處理丟失的列/表格。以後我可以解決這個問題,但是這是需要記住的事情,因爲我無法爲每個數據庫使用完全相同的模型。

任何有關此主題的資源,指針或閱讀材料都將得到真正的讚賞。在此先感謝,如果在別處回答了此問題,我很抱歉,搜索沒有顯示任何與此相關的內容。

編輯:我已經完整保留了原文,並且根據保羅的建議添加了更多內容。

RE:SA ORM - 是的,我打算使用SQLAlchemy ORM。對於可能的顯而易見的原因,我無法提供真正的數據庫。但是,假設這三個虛擬數據庫恰當地命名爲DB1,DB2和DB3(我們假設每個表都只有一個表格,只有幾列,但真實世界將會有更多的數據)。

每個數據庫都有一個用戶表,每個表中有幾列。以下是表/列的一些SQL註釋:

DB1.user --> DB1.user.id,  DB1.user.username, DB1.user.email 
DB2.user --> DB2.user.id,  DB2.user.user_name, DB2.user.email 
DB3._user --> DB3._user.userid, DB3._user.username, DB3.user.email_address 

目前,我試圖分離出這些數據庫爲「模塊化」,並能夠只需添加額外的數據庫,我去。

我已經考慮了幾個不同的文件組織方面的問題(假設存在__init__.py在需要的地方,但略去了的緣故),包括:

Databases   | Databases   | Databases 
    DB1.py  |  DB1    |  DB1 
    DB2.py  |   models.py |   models 
    DB3.py  |  DB2    |    user.py 
        |   models.py |    anothertable.py 
        |  DB2    |  ... 
        |   models.py |  DB3 
        |       |   models 
        |       |    user.py 
        |       |    anothertable.py 

我很想能夠與訪問這些SA ORM,並且在python文件中使用這些數據庫時儘可能少地導入/聲明。需要做類似的事情:

from sqlalchemy import create_engine 
from sqlalchemy.orm import sessionmaker 
from Database import DB1, ..., DB[N] 
db1_engine = create_engine('connect_string/db1') 
db1_session = sessionmaker(bind=db1_engine)() 
... 
db3_engine = create_engine('connect_string/db3') 
db3_session = sessionmaker(bind=db3_engine)() 

將是令人難以置信的繁瑣,因爲我將處理遠遠超過三個數據庫。我寧願有一個已經照顧我

能夠訪問和使用它相似(在__init__.py文件,也許?):

import Databases 

Databases.DB1.session.query('blahblah') 

將無限美好。

EDIT2:我也知道如何在設置我的模型時避開數據庫/列的命名約定中的變體。這不是一個問題,但我確實提到了它,以便知道我不能只爲一個數據庫使用一個模型集。

我希望通過擴大這個我沒有渾水或使這太混亂。感謝您花時間閱讀它!

EDIT3:我設法花了一點時間在這個上。我已經通過以下方式設置了該項目:

Databases 
    __init__.py 
    databases.py 
    settings.py 
    DB1 
     __init__.py 
     models.py 
    ... 
    DB3 
     __init__.py 
     models.py 

目前,我在settings.py文件中安裝了數據庫。每個條目都會像INSTALLED_DATABASES = ('DB1', ..., 'DB3')。當我完成更多模型時,他們會被添加到圖形列表中。這允許我隨時添加或刪除內容。

我在models.py文件中設置了引擎和sessios,並且將每個數據庫設置的init.py文件設置爲from models import *

在databases.py文件我有以下

class Databases(object): 
    def __init__(self): 
     for database in INSTALLED_DATABASES: 
      setattr(self, database, __import__(database)) 

我現在可以通過使用這些:

from databases import Databases 

db = Databases() 

for qr in db.DB1.query(db.DB1.User): 
    print qr.userid, qr.username 

SQLAlchemy的是讓我定義模型時手動指定的列名,其對我想要的標準化來說是一個巨大的好處。

我還有很多工作要做。我想創建強制模型驗證的對象(例如,是否存在字段?非現在字段是否具有默認值?等等),並更好地將它與我的IDE配合使用(它目前尚不存在)。但我走到了正確的軌道。我想我會更新這個爲任何人可能偶然想知道如何做同樣的事情,我是。

對不起,這已經很長了!

乾杯!

+0

我已經添加了一些額外的信息作爲EDIT3。我已經得到了它*有點*工作如何我想要它,但將需要繼續改善它。由於原文的範圍已經得到解答,我將不得不將這個問題延續到不同的問題中。所以,我不指望我會更新這個,除非我改變一些激進的東西,或者對它的工作方式作出嚴肅的進展。 如果有人對如何更好地做到這一點有任何建議,但我是全部耳朵。謝謝閱讀。 – Rejected 2013-03-11 17:00:55

+0

我不確定這可以幫助您解決問題,但也許它可以爲您添加一些內容。這是zzeek的一篇文章,在閱讀你的問題時,我被部分提醒了一下:http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy – javex 2013-03-13 22:57:20

+0

我會認真推薦把你最後的編輯,並將其作爲答案 - 這是一個很好的答案,並回答你自己的問題在這裏周圍笑了:-) – 2013-04-20 14:56:43

回答

5

按照上述要求與我最初的問題,我已經採取了我的第三個編輯,並使其我的答案。由於我不確定正確的協議,因此我已經在上面留下了第三個編輯。如果您已經閱讀過EDIT3,那麼您已經閱讀了我的答案。

我已經花了一點點時間在這個。我已經通過以下方式設置了該項目:

Databases 
    __init__.py 
    databases.py 
    settings.py 
    DB1 
     __init__.py 
     models.py 
    ... 
    DB3 
     __init__.py 
     models.py 

目前,我在settings.py文件中安裝了數據庫。每個條目都會像INSTALLED_DATABASES = ('DB1', ..., 'DB3')。當我完成更多模型時,他們會被添加到圖形列表中。這允許我隨時添加或刪除內容。

我在models.py文件中設置了引擎和sessios,並且將每個數據庫設置的init.py文件設置爲from models import *

在databases.py文件我有以下

class Databases(object): 
    def __init__(self): 
     for database in INSTALLED_DATABASES: 
      setattr(self, database, __import__(database)) 

我現在可以通過使用這些:

from databases import Databases 

db = Databases() 

for qr in db.DB1.query(db.DB1.User): 
    print qr.userid, qr.username 

SQLAlchemy的是讓我定義模型時手動指定的列名,其對我想要的標準化來說是一個巨大的好處。

我還有很多工作要做。我想創建強制模型驗證的對象(例如,是否存在字段?非現在字段是否具有默認值?等等),並更好地將它與我的IDE配合使用(它目前尚不存在)。但我走到了正確的軌道。我想我會更新這個爲任何人可能偶然想知道如何做同樣的事情,我是。

對不起,這已經很長了!

乾杯!

1

您的解決方案看起來不錯。這就是我所做的。

我有一個名爲連接器的包,並在其中爲每個數據庫以及一個設置文件模塊。

每個連接器模塊都會創建連接字符串及其引擎,以及表的聲明基礎和類。

然後有一個方法loadSession返回會話(這是我從一個教程或另一個職位在這裏得到的,不能準確回憶),另一個我添加,返回引擎,以防我想要做的事情。

所以後來在程序中的一些模塊,我會做這樣的事情

from connectors import x, y, z 

x_ses = x.loadSession() 
y_ses = y.loadSession() 
z_ses = z.loadSession() 

xq = x_ses.query(...) 
yq = y_ses.query(...) 
相關問題