SQLAlchemy和多个数据库

2024-04-26 04:53:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一系列类似(但不完全相同)的数据库,希望使用SQLAlchemy作为“标准化”访问的方法。数据库的差别可能非常小,例如列名上有一个唯一的前缀,或者它们的差别可能更大,可能是缺少列(或者对于旧数据库,缺少整个表)。

我要寻找的帮助与其说是一个SQLAlchemy问题,不如说是一个Python/组织问题。如何设置多个数据库,以便在项目中轻松重用?

我读过关于SQLAlchemy会话的文章,但是如果不在每个项目中实例化它们,就看不到使用它们的方法。

我的问题是:如何制作一个模块/包,它将包含许多数据库模型设置,以便在SQLAlchemy中使用,并且可以在另一个python项目中轻松导入/使用?

到目前为止,我还不太担心处理丢失的列/表。我可以在以后解决这个问题,但这是需要记住的,因为我不能为每个数据库使用完全相同的模型。

任何关于这个主题的资源,指南,或阅读材料都会被真正的感激。提前谢谢,很抱歉,如果这已经在其他地方得到答复,搜索没有显示任何与此相关的信息。

编辑:我保留了原稿,并根据保罗的建议添加了更多内容。

回复: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)()

会非常麻烦,因为我要处理的不仅仅是三个数据库。我更希望已经帮我处理好了(可能在uuinit_uuuuuuuuuuuuuuuuuuy.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')。当我完成更多的模型时,它们被添加到tupples列表中。这允许我在进行时添加或删除内容。

我在models.py文件中设置了引擎和会话,并将每个数据库设置的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结合起来(目前还没有)。但我走对了路。我想我会为那些想知道怎么做的人更新这个。

对不起,这已经太久了!

干杯!


Tags: 文件frompy模型import数据库sqlalchemyinit
2条回答

你的解决方案看起来不错。我就是这么做的。

我有一个名为connectors的包,其中有一个用于每个db的模块以及一个设置文件。

每个连接器模块都创建其连接字符串和引擎,以及表的声明性基和类。

然后有一个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(...)

根据对我最初问题的要求,我进行了第三次编辑,并给出了我的答案。由于我不确定合适的协议,我把上面的第三个编辑放在适当的位置。如果你已经读过EDIT3,那么你已经读过我的答案了。

我设法在这件事上多花点时间。我已按以下方式设置项目:

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

目前,我在settings.py文件中“安装”了一组数据库。每个DB条目都在INSTALLED_DATABASES = ('DB1', ..., 'DB3')中指定。当我完成更多的模型时,它们被添加到元组列表中。这允许我在进行时添加或删除内容。

我在models.py文件中设置了引擎和会话,并将每个数据库的__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结合起来(目前还没有)。但我走对了路。我想我会为那些想知道怎么做的人更新这个。

对不起,这已经太久了!

干杯!

相关问题 更多 >

    热门问题