将 isolation_level 添加到 apache mod_wsgi 服务器上的 flask-sqlalchemy 应用程序后,图像出现间歇性 500 内部服务器错误
Intermittent 500 internal server error in images after adding isolation_level to a flask-sqlalchemy app on apache mod_wsgi server
我在 flask-sqlalchemy、marshamllow 应用程序中使用 Apache mod_wsgi,使用 pyodbc 连接到远程 ms sql 数据库,最近我被要求添加 isolation_level '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 服务器访问图像 blob 数据并显示在网页上,添加隔离级别后不久,我看到每隔几张图像就会产生内部错误,执行 ctrl+f5显示图像,但还有其他图像未显示,这在错误日志中
mod_wsgi (pid=10694): 处理 WSGI 脚本时发生异常
pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Transaction failed in database 'testdb' 因为语句运行 在快照隔离下,但事务没有在快照隔离下启动。在事务启动后不能将事务的隔离级别更改为快照,除非事务最初是在快照隔离级别下启动的。(3951) ( SQLExecDirectW)")
编辑以添加以下代码:
当不使用 create-engine
时,我如何使用 flask-sqlalchmey 做到这一点
我的app.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()
在引擎级别
如果您使用的是 declaritive 实现,您将有权访问创建引擎函数(以及范围会话函数)。
但假设您使用的是 Flask-SQLAlchemy 实现,这只是在后台调用 sqlalchemy.create_engine
(on this line)。
对于后者来说可能是一个 hack,因为似乎没有办法将与引擎相关的选项传入;它们在 #558
:
中专门定义了几行
options = {'convert_unicode': True}
在会话级别
这看起来可能稍微容易一些,因为您可以在初始化 SQLAlchemy 时传递会话选项:see this line. The create_scoped_session
method expects a dictionary 可以作为 session_options
传递给 __init__
方法。
因此,当您初始化库时,您可以尝试类似的操作:
db = SQLiteAlchemy(session_options={'isolation_level': 'SNAPSHOT'})
我在 flask-sqlalchemy、marshamllow 应用程序中使用 Apache mod_wsgi,使用 pyodbc 连接到远程 ms sql 数据库,最近我被要求添加 isolation_level '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 服务器访问图像 blob 数据并显示在网页上,添加隔离级别后不久,我看到每隔几张图像就会产生内部错误,执行 ctrl+f5显示图像,但还有其他图像未显示,这在错误日志中 mod_wsgi (pid=10694): 处理 WSGI 脚本时发生异常 pyodbc.ProgrammingError: ('42000', "[42000] [Microsoft][ODBC Driver 13 for SQL Server][SQL Server]Transaction failed in database 'testdb' 因为语句运行 在快照隔离下,但事务没有在快照隔离下启动。在事务启动后不能将事务的隔离级别更改为快照,除非事务最初是在快照隔离级别下启动的。(3951) ( SQLExecDirectW)")
编辑以添加以下代码:
当不使用 create-engine
时,我如何使用 flask-sqlalchmey 做到这一点我的app.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()
在引擎级别
如果您使用的是 declaritive 实现,您将有权访问创建引擎函数(以及范围会话函数)。
但假设您使用的是 Flask-SQLAlchemy 实现,这只是在后台调用 sqlalchemy.create_engine
(on this line)。
对于后者来说可能是一个 hack,因为似乎没有办法将与引擎相关的选项传入;它们在 #558
:
options = {'convert_unicode': True}
在会话级别
这看起来可能稍微容易一些,因为您可以在初始化 SQLAlchemy 时传递会话选项:see this line. The create_scoped_session
method expects a dictionary 可以作为 session_options
传递给 __init__
方法。
因此,当您初始化库时,您可以尝试类似的操作:
db = SQLiteAlchemy(session_options={'isolation_level': 'SNAPSHOT'})