2016-01-16 1 views
3

Я использую кол-sqlalchemy в своем приложении. DB - postgresql 9.3. У меня есть простая инициализация БД, модель и представление:Flask-sqlalchemy потерять соединение после перезапуска сервера БД

from config import * 
from flask import Flask, request, render_template 
from flask.ext.sqlalchemy import SQLAlchemy 
app = Flask(__name__) 
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://%s:%[email protected]%s/%s' % (DB_USER, DB_PASSWORD, HOST, DB_NAME) 
db = SQLAlchemy(app) 

class User(db.Model): 
    id = db.Column(db.Integer, primary_key=True) 
    login = db.Column(db.String(255), unique=True, index=True, nullable=False) 

db.create_all() 
db.session.commit() 

@app.route('/users/') 
def users(): 
    users = User.query.all() 
    return '1' 

И все работает отлично. Но когда происходит сервер БД перезапуска (sudo service postgresql restart), по первому требованию к /users/ я получаю sqlalchemy.exc.OperationalError:

OperationalError: (psycopg2.OperationalError) terminating connection due to administrator command 
SSL connection has been closed unexpectedly 
[SQL: .... 

Есть ли способ, чтобы возобновить соединение внутри зрения или установки опоки-SQLAlchemy другим способом для возобновления соединения автоматически?

ОБНОВЛЕНИЕ.

Я закончил с использованием ясной SQLAlchemy, объявляя движок, метаданные и db_session для каждого представления, где мне это очень нужно.

Это не решение вопроса, просто «взломать».

Так что вопрос открыт. Я уверен, хорошо бы найти решение для этого :)

ответ

4

SQLAlchemy documentation объясняет, что поведение по умолчанию заключается в том, чтобы оптимизировать обработку отключений. Вы попробовали другой запрос - соединение должно было восстановить себя? Я только что проверил это с проектом Flask/Postgres/Windows, и он работает.

В типичном веб-приложении, использующем сеанс ORM, вышеуказанное условие будет соответствовать одиночному запросу с ошибкой 500, а затем веб-приложение, продолжающееся обычно за пределами этого. Следовательно, подход «оптимистичен» в том, что частые перезагрузки базы данных не ожидаются.

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

from sqlalchemy import exc 
from sqlalchemy import event 
from sqlalchemy.pool import Pool 

@event.listens_for(Pool, "checkout") 
def ping_connection(dbapi_connection, connection_record, connection_proxy): 
    cursor = dbapi_connection.cursor() 
    try: 
     cursor.execute("SELECT 1") 
    except: 
     # optional - dispose the whole pool 
     # instead of invalidating one at a time 
     # connection_proxy._pool.dispose() 

     # raise DisconnectionError - pool will try 
     # connecting again up to three times before raising. 
     raise exc.DisconnectionError() 
    cursor.close() 

Вот некоторые скриншоты случае поимки отладчик PyCharm в:

Windows 7 (Postgres 9.4, Колба 0.10.1, SQLAlchemy 1.0.11, Колба-SQLAlchemy 2,1 и Psycopg 2.6.1)

По первому требованию дб enter image description here После перезагрузки дб enter image description here

Ubuntu 14.04 (Postgres 9.4, 0.10.1 Колба, SQLAlchemy 1.0.8, Колба-SQLAlchemy 2.0 и Psycopg 2.5.5)

По запросу первого дб enter image description here После дб перезагрузкаenter image description here

+0

К сожалению, это не поможет. Первый запрос после перезапуска сервера БД это событие не выполняется. И если функция вызова ping_connection (params) внутри отображается, это не поможет. – user1931780

+0

@ user1931780 - interesting - Я запустил код через отладчик PyCharm (как на Windows, так и на Ubuntu), и перезагрузка была обработана, как и ожидалось. Я перечислил используемые версии библиотеки. – pjcunningham

+0

Отличный пост! Работает так, как ожидалось! Большое спасибо @pjcunningham! –

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