每个视图更改数据库&每个视图访问多个数据库

时间:2011-08-13 13:01:27

标签: python sqlalchemy pylons pyramid

我在Pyramid中使用SQLAlchemy时遇到了一些问题。虽然我可以找到我需要的例子,但它们通常很短而且缺乏。所以我最终得到的补丁代码几乎没有任何意义。所以我希望有人能够更全面地展示我需要做的事情。

我有4个数据库都具有相同的架构。我希望能够从一个金字塔应用程序处理它们,有时列出来自所有4个数据库的所有“订单”,有时只列出“site1”中的所有“订单”。由于模式相同,我也对数据库使用相同的模型类。

我已经尝试了sqlahelper和普通的SQLAlchemy而没有运气。下面的代码使用sqlahelper,但我很乐意使用任何有用的东西:

__初始化__。PY

site1_eng = engine_from_config(settings, prefix='site1.')
site2_eng = engine_from_config(settings, prefix='site2.')
site3_eng = engine_from_config(settings, prefix='site3.')

sqlahelper.add_engine(site1_eng, 'site1_eng')
sqlahelper.add_engine(site2_eng, 'site2_eng')

views.py

def site_orders(request):
    site = request.matchdict['site']
    db_eng = sqlahelper.get_engine(("%s_eng" % (site)))
    conn = db_eng.connect()
    dbsession = sqlahelper.get_session()
    dbsession.configure(bind=conn)

    orders = dbsession.query(Order).order_by(Order.cdate.desc())[:100]

    return dict(orders=orders, pagetitle=(site+" Orders"))

会发生什么?

好吧,我希望它会根据URL切换数据库,它确实可以!但是,选择哪个似乎是完全随机的。所以/ orders / site1 /有时会转到site2数据库,有时会转到site3。刷新通常会每次都切换它选择的数据库。其他网址也是如此。

它几乎就像会话没有绑定到数据库并且选择当时在会话中发生的那个?这可能没有意义 - 我对SQLAlchemy的理解并不是很好。

真的希望有人可以提供帮助,因为这一切都取决于能否快速轻松地在视图中切换数据库,而且目前似乎完全无法控制它。

注意: 我最初尝试关注和更改使用的Pyramid SQLA + URL Dispatcher教程:

DBSession = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))

但是在找到sqlahelper时我删除了它。如果我应该使用它,请告诉我。

2 个答案:

答案 0 :(得分:8)

为每个请求配置和连接对我来说似乎很多工作。我会在我的模型模块中创建四个会话处理程序,然后从中选择它们。

示例:

models/__init__.py

DBSession1 = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))  
DBSession2 = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))  
DBSession3 = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))  
DBSession4 = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))  
metadata1 = MetaData()                                                           
metadata2 = MetaData()                                                           
metadata3 = MetaData()                                                           
metadata4 = MetaData()                                                           

def initialize_sql(engines, drop_db=False):                                      
    DBSession1.configure(bind=engine[0])
    DBSession2.configure(bind=engine[1])                                            
    DBSession3.configure(bind=engine[2])                                            
    DBSession4.configure(bind=engine[3])                                            
    metadata1.bind = engine[0]                                            
    metadata2.bind = engine[1]                                            
    metadata3.bind = engine[2]                                            
    metadata4.bind = engine[3]  

然后在你看来:

from mypackage.models import DBSession1, DBSession2, DBSession3, DBSession4

def site_orders(request)                                                      
    site = request.matchdict['site']                                                      
    dbsession = globals().get("DBSession%d" % site)                                                      
    orders = dbsession.query(Order).order_by(Order.cdate.desc())[:100]                                                      
    return dict(orders=orders, pagetitle=(site+" Orders"))

答案 1 :(得分:1)

您可以直接将引擎设置为sqlalchemy会话

列出所有4个数据库中所有“订单”的示例:

def site_orders(request):
    ...
    orders = []
    for engine in engines:
        dbsession.bind = engine
        orders += dbsession.query(Order).order_by(Order.cdate.desc())[:100]

    return dict(orders=orders, pagetitle=(site+" Orders"))