2016-05-09 2 views
0

Я привык делать это:try-finally с SqlAlchemy: это хорошая привычка?

from sqlalchemy.orm import sessionmaker 
from sqlalchemy.engine import create_engine 

Session = sessionmaker() 
engine = create_engine("some connection db string", echo=False) 
Session.configure(bind=engine) 

db_con = Session() 

try: 
    # DB MANIPULATION 
finally: 
    db_con.close() 

Это хорошая привычка? Если да, то почему sqlalchemy не позволяет вам просто:

with Session() as db_con: 
    # DB MANIPULATION 

?

ответ

1

Нет, это не очень хорошая практика. Это легко забыть и сделает код более запутанным.

Вместо этого вы можете использовать контекстный менеджер contextlib.closing и сделать это единственным способом получить сеанс.

# Wrapped in a custom context manager for better readability 
@contextlib.contextmanager 
def get_session(): 
    with contextlib.closing(Session()) as session: 
     yield session 

with get_session() as session: 
    session.add(...) 
+0

Я не знал 'contextlib'. Код действительно чистый. Но о второй части вопроса, почему '' sqlalchemy' '' Session() 'не имеет' __enter __() 'и' __exit __() 'встроенных методов, по вашему мнению? –

+0

@MarcoSulla У меня нет на это мнения. Наверное, это потому, что существует «закрытие». Спросите у разработчиков – Daenyth

0

Во-первых, если вы закончили работу с сеансом, вы должны закрыть сеанс. session.close вернет соединение обратно в пул двигателей, и если вы выходите из программы, вы должны распоряжаться пулом двигателя engine.dispose.

Теперь на ваш вопрос. В большинстве случаев сеансы будут использоваться для приложений с большим сроком выполнения, таких как веб-сервер. Там, где имеет смысл централизовать управление сеансом. Например, в flask-sqlalchemy сеанс создается с запуском каждого веб-запроса и закрывается, когда запрос завершен.

+0

Что делать, если у вас нет эксклюзивного доступа к базе данных? –

+0

Я не уверен, как эксклюзивный доступ к базе данных приходит в картину. До тех пор, пока у вас есть доступ к базе данных, вы можете создать объект ** engine ** и, следовательно, пул соединений. – aviator

+0

Пул интересен, но я думаю, вы неправильно поняли его использование: http://docs.sqlalchemy.org/en/latest/core/pooling.html - как вы можете прочитать, пул создается движком, и уже есть пул по умолчанию. Просто db_con.close() на самом деле не удаляет соединение, но возвращает его в пул. Напротив, вы создадите сеанс и будете использовать его все время, что не очень хорошо, если соединение отключено или ваша база данных является общей, а одновременные подключения ограничены, поэтому вы не можете подключиться и оставаться, потому что вы будете увольнять через две минуты. –

Смежные вопросы