python-mysql-connector 1.16、django 1.6 和 python 3.2.3 的导入错误

2 投票
1 回答
1263 浏览
提问于 2025-04-17 23:13

我在一个虚拟环境中用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

撰写回答