环境说明:
Centos 7 + Python3.6 + Cesi 2.7.1
按照官网说明运行,服务启动正常,在登录界面输入密码后提示密码错误。
打开浏览器开发者工具,查看对应的登录POST请求,提示500错误。
回到cesi服务器,查看日志报错如下:
File "/lib/python3.6/site-packages/flask_sqlalchemy/__init__.py", line 915, in apply_driver_hacks
sa_url.database = os.path.join(app.root_path, sa_url.database)
AttributeError: can't set attribute
看一下异常位置
def apply_driver_hacks(self, app, sa_url, options): # sa_url输入参数
"""This method is called before engine creation and used to inject
driver specific hacks into the options. The `options` parameter is
a dictionary of keyword arguments that will then be used to call
the :func:`sqlalchemy.create_engine` function.
The default implementation provides some saner defaults for things
like pool sizes for MySQL and sqlite. Also it injects the setting of
`SQLALCHEMY_NATIVE_UNICODE`.
"""
if sa_url.drivername.startswith('mysql'):
sa_url.query.setdefault('charset', 'utf8')
if sa_url.drivername != 'mysql+gaerdbms':
options.setdefault('pool_size', 10)
options.setdefault('pool_recycle', 7200)
elif sa_url.drivername == 'sqlite':
pool_size = options.get('pool_size')
detected_in_memory = False
if sa_url.database in (None, '', ':memory:'):
detected_in_memory = True
from sqlalchemy.pool import StaticPool
options['poolclass'] = StaticPool
if 'connect_args' not in options:
options['connect_args'] = {}
options['connect_args']['check_same_thread'] = False
# we go to memory and the pool size was explicitly set
# to 0 which is fail. Let the user know that
if pool_size == 0:
raise RuntimeError('SQLite in memory database with an '
'empty queue not possible due to data '
'loss.')
# if pool size is None or explicitly set to 0 we assume the
# user did not want a queue for this sqlite connection and
# hook in the null pool.
elif not pool_size:
from sqlalchemy.pool import NullPool
options['poolclass'] = NullPool
# if it's not an in memory database we make the path absolute.
if not detected_in_memory:
sa_url.database = os.path.join(app.root_path, sa_url.database) #报错位置
unu = app.config['SQLALCHEMY_NATIVE_UNICODE']
if unu is None:
unu = self.use_native_unicode
if not unu:
options['use_native_unicode'] = False
很明显,这里应该是对输入参数sa_url的内部变量赋值触发当前python语法规则,可以确定是flask_sqlalchemy这个包和当前python版本不兼容的原因。
看下cesi的requirements.txt文件
flask==1.1.2
flask-sqlalchemy==2.4.3
psycopg2-binary==2.8.5
pymysql==0.9.3
tomlkit==0.5.11
要求flask-sqlalchemy==2.4.3,cesi的github上实例用的python3.4,我的环境是python3.6,显然我应该升级flask-sqlalchemy,所以升级到最新版本
pip install flask-sqlalchemy==2.5.1
重新运行cesi,一切正常,问题修复。