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

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

I have a website running with a mysql database using the sql-alchemy package that has suddenly broken. I have done some research and found that the expected issue is that the newest sql-alchemy update is handing flask-admin one more value than expected from

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


来源

建议的解决方法是编辑文件以接受第三个项目,但我无法使用我对环境的权限来执行此操作.


Source

The suggested fix is to edit the files to accept a third item but I am unable to do this with the permissions I have on my environment.

另一个答案链接到 github 上的存储库,但我不知道这对我有什么帮助.我对此很陌生,我不知道我是否应该克隆 repo,或者如果我应该这样做.

Another answer links to a repo on github but I cannot figure out how that helps me. I'm very new to this and I don't know if I am supposed to clone the repo or how exactly to do that if I am.

感谢任何帮助!

这里是错误转储

2018-01-22 20:01:59,593: [2018-01-22 20:01:59,592] 应用程序错误:/reservation/add [GET]
2018-01-22 20:01:59,594 上的异常:回溯(最近一次调用最后一次):
2018-01-22 20:01:59,594:
文件fakepath/flask/app.py",第 1982 行,在 wsgi_app
2018-01-2220:01:59,594: response = self.full_dispatch_request()2018-01-22 20:01:59,594: 文件fakepath/flask/app.py",第 1614 行,在 full_dispatch_request
2018-01-22 20:01:59,594: rv =self.handle_user_exception(e)
2018-01-22 20:01:59,595:文件"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: 文件"flask/fakepath_compat.py", 行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,在 full_dispatch_request
2018-01-22 20:01:59,595: rv =self.dispatch_request()
2018-01-22 20:01:59,596:文件fakepath/flask/app.py",第 1598 行,在 dispatch_request2018-01-22 20:01:59,596 中:返回self.view_functionsrule.endpoint
2018-01-2220:01:59,596:文件fakepath/flask_login/utils.py",第 261 行,在装饰视图
2018-01-22 20:01:59,596: 返回 func(*args,**kwargs)
2018-01-22 20:01:59,597:文件/home/apoalphagammawebmaster/inventory/app/auth/views.py",第 248 行,在 add_reservation
2018-01-22 20:01:59,597: form=form,title='添加预订')
2018-01-22 20:01:59,597: 文件"fakepath/flask/templating.py", line 134, in render_template2018-01-22 20:01:59,597: context, ctx.app)
2018-01-2220:01:59,597:文件fakepath/flask/templating.py",第 116 行,在_render
2018-01-22 20:01:59,597: rv = template.render(context)
2018-01-22 20:01:59,598: 文件fakepath/jinja2/asyncsupport.py",第 76 行,在渲染中
2018-01-2220:01:59,598:返回 original_render(self, *args, **kwargs)2018-01-22 20:01:59,598:文件fakepath/jinja2/environment.py",第 1008 行,在渲染中
2018-01-22 20:01:59,598:返回self.environment.handle_exception(exc_info, True)
2018-01-2220:01:59,598:文件fakepath/jinja2/environment.py",第 780 行,在handle_exception
2018-01-22 20:01:59,599:再加注(exc_type,exc_value, tb)
2018-01-22 20:01:59,599: 文件fakepath/jinja2/_compat.py",第 37 行,再次加注
2018-01-2220:01:59,599:提高 value.with_traceback(tb)
2018-01-2220:01:59,599:文件"/home/apoalphagammawebmaster/inventory/app/templates/auth/reservations/reservation.html",第 2 行,在顶级模板代码中
2018-01-22 20:01:59,599:
{% extends "base.html" %}
2018-01-22 20:01:59,599: 文件/home/apoalphagammawebmaster/inventory/app/templates/base.html",行48、在顶层模板代码
2018-01-22 20:01:59,600: {%块体 %}
2018-01-22 20:01:59,600:文件"/home/apoalphagammawebmaster/inventory/app/templates/auth/reservations/reservation.html",第 27 行,在body"块中
2018-01-22 20:01:59,600:{{wtf.quick_form(form) }}
2018-01-22 20:01:59,600: 文件fakepath/jinja2/runtime.py",第 579 行,在 _invoke
2018-01-2220:01:59,600: rv = self._func(*arguments)
2018-01-2220:01:59,601:文件fakepath/flask_bootstrap/templates/bootstrap/wtf.html",第 205 行,在模板
2018-01-22 20:01:59,601: {{ form_field(field,2018-01-22 20:01:59,601: 文件fakepath/jinja2/runtime.py", line579, 在 _invoke
2018-01-22 20:01:59,601: rv =self._func(*arguments)
2018-01-22 20:01:59,601: 文件fakepath/flask_bootstrap/templates/bootstrap/wtf.html",第 123 行,在模板
2018-01-22 20:01:59,601:
{{field(class="form-control", **kwargs)|safe}}
2018-01-2220:01:59,601:文件fakepath/wtforms/fields/core.py",第 153 行,在调用
2018-01-22 20:01:59,601:返回 self.meta.render_field(self, kwargs)
2018-01-22 20:01:59,602:
文件fakepath/wtforms/meta.py",第 56 行,在 render_field2018-01-22 20:01:59,602: return field.widget(field,**render_kw)
2018-01-22 20:01:59,602:文件fakepath/wtforms/widgets/core.py",第 287 行,调用2018-01-22 20:01:59,602: 对于 val, label, selected infield.iter_choices():
2018-01-22 20:01:59,602: 文件fakepath/wtforms/ext/sqlalchemy/fields.py",第 107 行,在iter_choices
2018-01-22 20:01:59,602: 对于 pk, obj inself._get_object_list():
2018-01-22 20:01:59,602: 文件fakepath/wtforms/ext/sqlalchemy/fields.py",第 100 行,在_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-2220:01:59,603:文件fakepath/wtforms/ext/sqlalchemy/fields.py",行100, 在
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", line189, 在 get_pk_from_identity
2018-01-22 20:01:59,603: cls,key = identity_key(instance=obj)
2018-01-22 20:01:59,603:值错误:解包的值太多(预期为 2)

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

The problem is covered on the github issues thread - https://github.com/flask-admin/flask-admin/issues/1588

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

Basically, the flask-admin pip package is out of date, in regards the latest sqlalchemy pip package. In that specific area,

cls, key = identity_key(instance=obj)

sqlalchemy 现在返回 3 个对象,但 flask-admin 只需要 2 个,因此出现错误.

sqlalchemy is now returning 3 objects, but flask-admin is only expecting 2, hence the error.

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

The real solution for this is to wait until a new flask-admin version is uploaded to pip, until then, you've a few options.

  1. 手动进入并编辑fields.py文件
  2. 如该问题线程中所述,将 sqlalchemy 限制为版本 1.2.0b3.您可以在 requirements.txt 文件中执行此操作,也可以使用 pip 升级安装手动执行此操作,pip install --upgrade sqlalchemy==1.2.0b3
  3. 由于修复程序位于 flask-admin 的 github 存储库中的 master 分支中,请使用 git 的 pip 位置安装该版本的 flask-admin+https://github.com/flask-admin/flask-admin.同样,您在 requirements.txt 文件中执行此操作,或者使用 pip 升级安装,pip install --upgrade git+https://github.com/flask-admin/flask-admin.
  1. Manually go in and edit that fields.py file
  2. As detailed in that issues thread, limit sqlalchemy to version 1.2.0b3. You can do this in your requirements.txt file, or manually with a pip upgrade install, pip install --upgrade sqlalchemy==1.2.0b3
  3. As the fix is in flask-admin's master branch in their github repository, install that version of flask-admin with the pip location of git+https://github.com/flask-admin/flask-admin. Again, you do this in your requirements.txt file, or with a pip upgrade install, pip install --upgrade git+https://github.com/flask-admin/flask-admin.

我个人的偏好,以及我所做的,是选项 3.如果你仔细查看代码本身,无论如何,这是维护者想要删除的一行,并且他们如何处理它更好,并且在对于这些事情,我更喜欢前进(最新版本的 flask-admin)而不是阻止事情(回滚 sqlalchemy 到以前的版本),当然比手动编辑原始代码.

My personal preference, and what I've done, is option 3. If you look through the code itself, it's a line the maintainers want to remove, anyway, and how they're dealing with it is better, and in general with these things, I prefer to go forward (latest version of flask-admin) rather than holding things back (rollback sqlalchemy to a previous version), and certainly better than manually editing the raw code.

相关文章