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.
- 手动进入并编辑
fields.py
文件 - 如该问题线程中所述,将
sqlalchemy
限制为版本1.2.0b3
.您可以在 requirements.txt 文件中执行此操作,也可以使用 pip 升级安装手动执行此操作,pip install --upgrade sqlalchemy==1.2.0b3
- 由于修复程序位于
flask-admin
的 github 存储库中的 master 分支中,请使用git 的 pip 位置安装该版本的
.同样,您在 requirements.txt 文件中执行此操作,或者使用 pip 升级安装,flask-admin
+https://github.com/flask-admin/flask-adminpip install --upgrade git+https://github.com/flask-admin/flask-admin
.
- Manually go in and edit that
fields.py
file - As detailed in that issues thread, limit
sqlalchemy
to version1.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
- As the fix is in
flask-admin
's master branch in their github repository, install that version offlask-admin
with the pip location ofgit+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.
相关文章