2013-03-07 118 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(...) 
相关问题