Периодическая внутренняя ошибка сервера 500 в изображениях после добавления изолированного уровня в приложение flask-sqlalchemy на сервере apache mod_wsgi - PullRequest
0 голосов
/ 12 февраля 2019

Я использую Apache mod_wsgi в приложении flask-sqlalchemy, marshamllow, подключаюсь к удаленной базе данных ms sql с помощью pyodbc, недавно меня попросили добавить изоляционный уровень 'SNAPSHOT', и я сделал это с помощью apply_driver_hacks

class SQLiteAlchemy(SQLAlchemy):
def apply_driver_hacks(self, app, info, options):
    options.update({
        'isolation_level': 'SNAPSHOT',
    })
    super(SQLiteAlchemy, self).apply_driver_hacks(app, info, options)

проект построен для доступа к данным больших двоичных изображений с сервера ms sql и отображения на веб-странице, вскоре после добавления уровня изоляции я вижу внутреннюю ошибку, сгенерированную для каждых нескольких изображений, выполнение Ctrl + F5 отображает изображение, но затем появляютсядругие изображения не отображаются, и это в журнале ошибок. mod_wsgi (pid = 10694): Произошла исключительная ситуация при обработке сценария WSGI pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft] [Драйвер ODBC 13 для SQL Server] [SQLСервер] Транзакция завершилась неудачно в базе данных «testdb», так как оператор был запущен в режиме изоляции моментального снимка, но транзакция не началась в изоляции моментального снимка. Уровень изоляции транзакции нельзя изменить на моментальный снимок после ее запуска, если только транзакция не была исходнойЛли начал с уровня изоляции снимков.(3951) (SQLExecDirectW) ")

отредактировано для добавления кода ниже:

как мне сделать это с flask-sqlalchmey, когда не используется create-engine

моего приложения.py файл

app = Flask(__name__)
app.config.from_object('config.ProductionConfig')
db.init_app(app)
ma.init_app(app)

мой файл model.py

class SQLiteAlchemy(SQLAlchemy):
def apply_driver_hacks(self, app, info, options):
    options.update({
        'isolation_level': 'SNAPSHOT',
    })
    super(SQLiteAlchemy, self).apply_driver_hacks(app, info, options)

# To be initialized with the Flask app object in app.py.
db = SQLiteAlchemy()
ma = Marshmallow()

1 Ответ

0 голосов
/ 12 февраля 2019

На уровне двигателя

Если бы вы использовали реализацию с указанием , у вас был бы доступ к функции создания механизма (и к сеансу с определенными областями).

Но при условиивы используете реализацию Flask-SQLAlchemy, это просто вызывает sqlalchemy.create_engine под капотом (в этой строке) .

Может быть взломать для последнего, так как неткажется, способ передать опции, связанные с двигателем;они определены определенно на несколько строк вверх по #558:

options = {'convert_unicode': True}

на уровне сеанса

Похоже, это может быть немного проще, потому что вы можете передавать параметры сеанса при инициализации SQLAlchemy: см. Эту строку .Метод create_scoped_session ожидает словарь , который может быть передан методу __init__ как session_options.

Так что при инициализации библиотеки вы можете попробовать что-то вроде:

db = SQLiteAlchemy(session_options={'isolation_level': 'SNAPSHOT'})
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...