python-mysql-connector 1.16、django 1.6 和 python 3.2.3 的导入错误
我在一个虚拟环境中用Python 3.2.3运行Django 1.6和django-rest-framework,并且刚刚通过源代码安装了python-mysql-connector 1.1.6,主机是Ubuntu。
当我运行syncdb并启动项目时,一切都正常,但当我访问任何不是根目录的URL时,就会出现来自python-mysql-connector的导入错误:
Exception Value:
cannot import name zip_longest
Exception Location: /usr/local/dev/python3.2.3/lib/python3.2/site-packages/mysql/connector/django/compiler.py in <module>, line 6
这是出问题的那一行:
from django.utils.six.moves import zip_longest
如果我激活我的虚拟环境中的Python二进制文件,我就能成功运行那个导入语句。那么这是怎么回事呢?
>>>>from django.utils.six.moves import zip_longest
>>>>
这是我在虚拟环境中运行Django时的pip列表输出,用来确认我安装了所有正确的组件:
(python3.2.3)thegooch@yrmomsapt:~/$ pip list
Django (1.6.2)
djangorestframework (2.3.13)
Markdown (2.4)
mysql-connector-python (1.1.6)
pip (1.5.4)
setuptools (2.2)
wsgiref (0.1.2)
1 个回答
0
经过研究代码,我发现引用那个导入的时候出现了一些错误。我查看了/lib/python3.2/site-packages/django/utils/six.py文件,发现了与moves.zip_longest模块相关的引用。
首先是这个引用:
moves = sys.modules[__name__ + ".moves"] = _MovedItems(__name__ + ".moves")
这意味着它在调用_MovedItems类,而这里就是我模块的引用,正是因为这个引用导致了问题。
class _MovedItems(_LazyModule):
"""Lazy loading of moved objects"""
_moved_attributes = [
MovedAttribute("zip_longest", "itertools", "itertools", "izip_longest", "zip_longest")
class MovedAttribute(_LazyDescr):
def __init__(self, name, old_mod, new_mod, old_attr=None, new_attr=None):
super(MovedAttribute, self).__init__(name)
if PY3:
if new_mod is None:
new_mod = name
self.mod = new_mod
if new_attr is None:
if old_attr is None:
new_attr = name
else:
new_attr = old_attr
self.attr = new_attr
然后这个类是从_LazyDescr类继承的,但这个类比较简单。我不太清楚问题出在哪里,如果你把传入MovedAttribute构造函数的元组映射一下,它能正确地将旧版本映射到新版本。我不确定为什么会失败,但如果你在compiler.py文件中去掉那个导入语句,直接调用itertools的zip_longest,就能正常工作。
这看起来是这样的。如果你使用的是Python 3,请编辑/lib/python3.2/site-packages/mysql/connector/django/compiler.py文件,把第6行从这个:
from django.utils.six.moves import zip_longest as six_zip_longest
改成这个:
from itertools import zip_longest