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


У меня возникли проблемы с использованием 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. Если я буду использовать это, дайте мне знать.


4


источник


Ответы:


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

Пример:

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"))

8



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

1