Pylons: совместное использование SQLAlchemy MySQL с внешней библиотекой - PullRequest
1 голос
/ 29 октября 2010

Я запускаю Pylons, используя SQLAlchemy для подключения к MySQL, поэтому, когда я хочу использовать соединение с базой данных в контроллере, я могу сделать это:

from myapp.model.meta import Session

class SomeController(BaseController):
    def index(self):
        conn = Session.connection()
        rows = conn.execute('SELECT whatever')
...

Скажем, мой контроллер должен вызвать внешнийбиблиотека, которая также нуждается в соединении с базой данных, и я хочу предоставить соединение для него из соединения SQLAlchemy MySQL, которое уже установлено:

from myapp.model.meta import Session

import mymodule

class SomeController(BaseController):
    def index(self):
        conn = Session.connection()
        myobject = mymodule.someobject(DATABASE_OBJECT)
        ...
        conn.close()

Каким должен быть DATABSE_OBJECT?Возможности:

  1. Pass Session - а затем открыть и закрыть Session.connection() в коде модуля
  2. Pass conn, а затем вызвать conn.close() в контроллере
  3. Просто передайте параметры соединения, и код модуля установит свое собственное соединение

Есть еще одна складка, которая заключается в том, что мне нужно создать экземпляры некоторых объектов в app_globals.py, иэти объекты также нуждаются в подключении к базе данных.Кажется, что app_globals.py не может использовать соединение SQLAlchemy Session - оно еще не ограничено.

Является ли моя архитектура принципиально несостоятельной?Разве я не должен пытаться делить связи между Pylons и внешними библиотеками таким образом?Спасибо!

Ответы [ 2 ]

2 голосов
/ 29 октября 2010

Вы не должны сами управлять соединениями - все это делает SQLAlchemy. Просто используйте объект сеанса с заданной областью повсюду, и все будет в порядке.

def init_model(engine):
    sm = orm.sessionmaker(autoflush=False, autocommit=False, expire_on_commit=False, bind=engine)
    meta.engine = engine
    meta.Session = orm.scoped_session(sm)

def index(self):
    rows = Session.execute('SELECT ...')

Вы можете передать объект Session в вашу внешнюю библиотеку и выполнять запросы там, где пожелаете. Для этого нет необходимости вызывать .close ().

Что касается app_globals, я решил это, добавив другой метод в класс globals, который вызывается после инициализации db из environment.py

class Globals(...):
    def init_model(self, config):
        self.some_persistent_db_object = Session.execute('...')

def load_environment(...):
    ...
    config['pylons.app_globals'].init_model(config)
    return config
1 голос
/ 29 октября 2010
Каким должен быть DATABSE_OBJECT? Возможности:

4. передать «прокси» или «вспомогательный» объект с более высоким уровнем интерфейса абстракции

Если внешней библиотеке действительно не нужен прямой доступ к сеансу SQLAlchemy, вы можете предоставить ей объект, который имеет методы, такие как "get_account (account_no)" вместо "execute (sql)". Это сделает код, специфичный для SQLAlchemy, более изолированным, и его также будет проще тестировать.

Извините, что это не столько ответ на ваш первоначальный вопрос, сколько предложение дизайна.

...