Остановите sqlalchemy от управления соединением - PullRequest
0 голосов
/ 19 марта 2019

Я пытаюсь инициализировать SQLAlchemy с существующим подключением к БД, но мне бы хотелось, чтобы он полностью прекратил управлять им (открытие, закрытие, откат и т. Д.).Это потому, что я использую его вместе с другим ORM (django), а SQLAlchemy на самом деле является лишь способом выполнения более сложных запросов.Он будет использоваться только для чтения, и я просто хочу, чтобы он взял соединение, использовал его и оставил как есть.

Что я пробовал до сих пор:

from sqlalchemy.pool import NullPool
from sqlalchemy import create_engine
from django.db import connection

class DummyNullPool(NullPool):
    def _do_return_conn(self, conn):
        # avoid closing the connection as it belongs to django
        # orm, sql alchemy is only a tool to read

        pass

def get_engine(dummy=True):
    kwargs = {}
    if dummy:
        kwargs['poolclass'] = DummyNullPool
        kwargs['creator'] = lambda: connection.connection

    return create_engine(conn_string, **kwargs)

Это почти работает,но он зависает (хотя и не всегда) на

 def _create_connection(self):
     return _ConnectionRecord(self, False)

Так что я предполагаю, что должно быть какое-то условие гонки.

Причина, по которой я хочу повторно использовать то же соединение, заключается в том, что янравится иметь доступ к записям, созданным внутри текущей транзакции.

1 Ответ

0 голосов
/ 19 марта 2019

Хорошо, я думаю, что нашел способ, который "работает":

from django.conf import settings
from django.db import connection
from sqlalchemy.pool import NullPool
from sqlalchemy import create_engine as sa_create_engine

def do_nothing(dbapi_connection):
    return

def create_engine(db_name='default'):
    db = settings.DATABASES[db_name]

    conn_string = 'postgresql://{}{}@{}:{}/{}'.format(
        db['USER'],
        ':' + db['PASSWORD'] if db['PASSWORD'] else '',
        db['HOST'],
        db['PORT'],
        db['NAME']
    )

    engine = sa_create_engine(
        conn_string,
        poolclass=NullPool,
        creator=lambda: connection.connection
    )
    engine.dialect.do_close = do_nothing
    engine.dialect.do_commit = do_nothing
    engine.dialect.do_rollback = do_nothing
    return engine

Обратите внимание, что он не был полностью протестирован, это своего рода экспериментальный код. Предполагается, что connection.connection был инициализирован и открыт. Любые комментарии приветствуются.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...