SQL-炼金术:ValueError 值太多无法解压?

SQL-alchemy: ValueError too many values to unpack?

我有一个网站 运行 和一个 mysql 数据库,它使用 sql-alchemy 软件包,但突然损坏了。我做了一些研究,发现预期的问题是最新的 sql-alchemy 更新给 flask-admin 带来的价值比预期的多

"cls, key = identity_key(instance=obj)"


Source

建议的修复方法是编辑文件以接受第三项,但我无法使用我在我的环境中拥有的权限执行此操作。

另一个答案链接到 github 上的回购协议,但我不知道这对我有何帮助。我对此很陌生,我不知道我是否应该克隆回购协议,或者如果我是,我不知道该怎么做。

感谢任何帮助!

这是错误转储

2018-01-22 20:01:59,593: [2018-01-22 20:01:59,592] ERROR in app: Exception on /reservation/add [GET]
2018-01-22 20:01:59,594: Traceback (most recent call last):
2018-01-22 20:01:59,594:
File "fakepath/flask/app.py", line 1982, in wsgi_app
2018-01-22 20:01:59,594: response = self.full_dispatch_request()2018-01-22 20:01:59,594: File "fakepath/flask/app.py", line 1614, in full_dispatch_request
2018-01-22 20:01:59,594: rv = self.handle_user_exception(e)
2018-01-22 20:01:59,595: File "fakepath/flask/app.py", line 1517, in handle_user_exception2018-01-22 20:01:59,595: reraise(exc_type, exc_value, tb)2018-01-22 20:01:59,595: File "fakepath/flask/_compat.py", line 33, in reraise
2018-01-22 20:01:59,595: raise value2018-01-22 20:01:59,595: File "fakepath/flask/app.py", line 1612, in full_dispatch_request
2018-01-22 20:01:59,595: rv = self.dispatch_request()
2018-01-22 20:01:59,596: File "fakepath/flask/app.py", line 1598, in dispatch_request2018-01-22 20:01:59,596: return self.view_functionsrule.endpoint
2018-01-22 20:01:59,596: File "fakepath/flask_login/utils.py", line 261, in decorated_view
2018-01-22 20:01:59,596: return func(*args, **kwargs)
2018-01-22 20:01:59,597: File "/home/apoalphagammawebmaster/inventory/app/auth/views.py", line 248, in add_reservation
2018-01-22 20:01:59,597: form=form, title='Add Reservation')
2018-01-22 20:01:59,597: File "fakepath/flask/templating.py", line 134, in render_template2018-01-22 20:01:59,597: context, ctx.app)
2018-01-22 20:01:59,597: File "fakepath/flask/templating.py", line 116, in _render
2018-01-22 20:01:59,597: rv = template.render(context)
2018-01-22 20:01:59,598: File "fakepath/jinja2/asyncsupport.py", line 76, in render
2018-01-22 20:01:59,598: return original_render(self, *args, **kwargs)2018-01-22 20:01:59,598: File "fakepath/jinja2/environment.py", line 1008, in render
2018-01-22 20:01:59,598: return self.environment.handle_exception(exc_info, True)
2018-01-22 20:01:59,598: File "fakepath/jinja2/environment.py", line 780, in handle_exception
2018-01-22 20:01:59,599: reraise(exc_type, exc_value, tb)
2018-01-22 20:01:59,599: File "fakepath/jinja2/_compat.py", line 37, in reraise
2018-01-22 20:01:59,599: raise value.with_traceback(tb)
2018-01-22 20:01:59,599: File "/home/apoalphagammawebmaster/inventory/app/templates/auth/reservations/reservation.html", line 2, in top-level template code
2018-01-22 20:01:59,599:
{% extends "base.html" %}
2018-01-22 20:01:59,599: File "/home/apoalphagammawebmaster/inventory/app/templates/base.html", line 48, in top-level template code
2018-01-22 20:01:59,600: {% block body %}
2018-01-22 20:01:59,600: File "/home/apoalphagammawebmaster/inventory/app/templates/auth/reservations/reservation.html", line 27, in block "body"
2018-01-22 20:01:59,600: {{ wtf.quick_form(form) }}
2018-01-22 20:01:59,600: File "fakepath/jinja2/runtime.py", line 579, in _invoke
2018-01-22 20:01:59,600: rv = self._func(*arguments)
2018-01-22 20:01:59,601: File "fakepath/flask_bootstrap/templates/bootstrap/wtf.html", line 205, in template
2018-01-22 20:01:59,601: {{ form_field(field,2018-01-22 20:01:59,601: File "fakepath/jinja2/runtime.py", line 579, in _invoke
2018-01-22 20:01:59,601: rv = self._func(*arguments)
2018-01-22 20:01:59,601: File "fakepath/flask_bootstrap/templates/bootstrap/wtf.html", line 123, in template
2018-01-22 20:01:59,601:
{{field(class="form-control", **kwargs)|safe}}
2018-01-22 20:01:59,601: File "fakepath/wtforms/fields/core.py", line 153, in call
2018-01-22 20:01:59,601: return self.meta.render_field(self, kwargs)
2018-01-22 20:01:59,602:
File "fakepath/wtforms/meta.py", line 56, in render_field2018-01-22 20:01:59,602: return field.widget(field, **render_kw)
2018-01-22 20:01:59,602: File "fakepath/wtforms/widgets/core.py", line 287, in call2018-01-22 20:01:59,602: for val, label, selected in field.iter_choices():
2018-01-22 20:01:59,602: File "fakepath/wtforms/ext/sqlalchemy/fields.py", line 107, in iter_choices
2018-01-22 20:01:59,602: for pk, obj in self._get_object_list():
2018-01-22 20:01:59,602: File "fakepath/wtforms/ext/sqlalchemy/fields.py", line 100, in _get_object_list
2018-01-22 20:01:59,602: self._object_list = list((text_type(get_pk(obj)), obj) for obj in query)
2018-01-22 20:01:59,603: File "fakepath/wtforms/ext/sqlalchemy/fields.py", line 100, in
2018-01-22 20:01:59,603: self._object_list = list((text_type(get_pk(obj)), obj) for obj in query)
2018-01-22 20:01:59,603: File "fakepath/wtforms/ext/sqlalchemy/fields.py", line 189, in get_pk_from_identity
2018-01-22 20:01:59,603: cls, key = identity_key(instance=obj)
2018-01-22 20:01:59,603: ValueError: too many values to unpack (expected 2)

问题已在 github 问题线程中解决 - https://github.com/flask-admin/flask-admin/issues/1588

基本上,关于最新的 sqlalchemy pip 包,flask-admin pip 包已经过时了。在那个特定区域,

cls, key = identity_key(instance=obj)

sqlalchemy 现在返回 3 个对象,但 flask-admin 只期望返回 2 个对象,因此出现错误。

真正的解决方案是等到新的flask-admin版本上传到pip,在那之前,你有几个选择。

  1. 手动进入并编辑那个fields.py文件
  2. 如该问题帖中所述,将 sqlalchemy 限制为版本 1.2.0b3。您可以在 requirements.txt 文件中执行此操作,或者使用 pip 升级安装手动执行此操作,pip install --upgrade sqlalchemy==1.2.0b3
  3. 由于修复在 flask-admin 的 github 存储库中的 master 分支中,因此请使用 git+https://github.com/flask-admin/flask-admin 的 pip 位置安装该 flask-admin 版本。同样,您可以在 requirements.txt 文件中执行此操作,或者使用 pip 升级安装 pip install --upgrade git+https://github.com/flask-admin/flask-admin.

我个人的偏好,也是我所做的,是选项 3。如果你仔细查看代码本身,这是维护人员想要删除的一行,无论如何,他们如何处理它更好,总的来说,对于这些事情,我更愿意继续前进(flask-admin 的最新版本)而不是阻止事情发生(回滚 sqlalchemy 到以前的版本),而且肯定比手动编辑原始代码更好。

我也遇到了这个问题。我得到了 hack(如上所述)的工作,但看看 https://github.com/wtforms/wtforms/issues/373 and https://github.com/flask-admin/flask-admin/issues/1588 上的讨论,看起来对 wtforms_sqlalchemy 的支持不如 wtforms_alchemy。

所以,我安装了 wtforms_alchemy

pip install wtforms_alchemy 

并在我的项目中将 wtforms_sqlalchemy 替换为 wtform_alchemy

from wtforms_alchemy.fields import QuerySelectField 

我的项目也一样。