Изменение базы данных для каждого представления и доступ к нескольким базам данных для каждого представления

У меня возникли проблемы с использованием SQLAlchemy в Pyramid. Хотя я могу найти примеры того, что мне нужно, обычно они очень короткие и отсутствуют. Так что я получил неоднородный код, который едва ли имеет какой-либо смысл. Поэтому я надеюсь, что кто-то может привести более полный пример того, что мне нужно сделать.

У меня есть 4 базы данных с одинаковой схемой. Я хочу иметь возможность работать с ними из одного приложения Pyramid, иногда перечисляя все «заказы» из всех 4 баз данных, иногда просто перечисляя все «заказы» с «site1». Поскольку схемы одинаковы, я также использую одни и те же классы моделей для баз данных.

Я пробовал это как с sqlahelper, так и с простым SQLAlchemy, но безуспешно. В приведенном ниже коде используется sqlahelper, но я рад использовать все, что работает:

__init__.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. Обновление часто переключает базу данных, которую она выбирает каждый раз. То же самое для других URL-адресов.

Это похоже на то, как если бы сеанс не был привязан к базе данных, и его выбор не зависит от того, что происходит в сеансе в данный момент? Это может не иметь смысла - мое понимание SQLAlchemy невелико.

Очень надеюсь, что кто-то может помочь, так как все зависит от возможности быстро и легко переключать базы данных в представлении, и на данный момент кажется совершенно невозможным управлять этим.

ПРИМЕЧАНИЕ. Первоначально я пытался следовать и изменять руководство Pyramid SQLA+URL Dispatcher, которое использовало:

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

Но я удалил это, найдя sqlahelper. Если я должен использовать его, дайте мне знать.


person RustyFluff    schedule 13.08.2011    source источник


Ответы (2)


Настройка и подключение для каждого запроса кажется мне большой работой. Я бы создал четыре обработчика сеансов в моем модуле модели и просто выбирал из них.

Пример:

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"))
person Mariano    schedule 13.08.2011

Вы можете напрямую настроить движок на сеанс 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"))
person estin    schedule 15.08.2011