【问题标题】:Django import export - Unable to import model with BinaryFieldDjango import export - 无法使用 BinaryField 导入模型
【发布时间】:2017-12-19 09:56:24
【问题描述】:

我正在尝试从具有可为空的BinaryField 的模型导入数据。数据不包含该字段,我希望在该字段中使用空值导入它。如果给定id 的数据库中已经存在该字段,则它应该保持原来的值。

我从对应Resource对象的fields白名单中删除了该字段,并将其添加到exclude黑名单中。但是,我在导入时遇到此错误 - can't pickle memoryview objects

追溯:

Traceback (most recent call last):
File "/lib/python3.5/site-packages/import_export/resources.py", line 451, in import_row
original = deepcopy(instance)
File "/lib/python3.5/copy.py", line 182, in deepcopy
y = _reconstruct(x, rv, 1, memo)
File "/lib/python3.5/copy.py", line 297, in _reconstruct
state = deepcopy(state, memo)
File "/lib/python3.5/copy.py", line 155, in deepcopy
y = copier(x, memo)
File "/lib/python3.5/copy.py", line 243, in _deepcopy_dict
y[deepcopy(key, memo)] = deepcopy(value, memo)
File "/lib/python3.5/copy.py", line 174, in deepcopy
rv = reductor(4)
TypeError: can't pickle memoryview objects

软件包版本 - django==1.11、django-import-export==0.6

编辑:

class ABC(models.Model):
    name = models.CharField('Name', max_length=128, blank=False, null=False)
    binary_field = models.BinaryField('Some name', null=True, blank=True)

class ABCResource(resources.ModelResource):
    class Meta:
        model = ABC
        fields = (
            'id',
            'name',
        )
        import_id_fields = ('id',)
        exclude = ('binary_field',)

class ABCAdmin(ImportExportModelAdmin):
    form = ABCModelForm
    list_display = (
        'id',
        'name',
    )
    exclude = ('binary_field',)
    resource_class = ABCResource

class ABCModelForm(forms.ModelForm):
    class Meta:
        model = ABC
        exclude = ['binary_field']

【问题讨论】:

  • 专有代码,所以添加了它的简化版本...
  • 你使用的是什么版本的django-import-export
  • django-import-export 是 0.6
  • 脑子放屁,对不起。 @Roshan 最新的 0.7 版本会出现这种情况吗?
  • 使用 django import export 甚至尝试在应用程序级别转储数据库确实是对资源、时间和精力的巨大浪费。使用为此定制的工具 - 这是您的数据库转储工具。

标签: python django django-import-export


【解决方案1】:

遗憾的是,这似乎是 django-import-export 模块的问题。

在 Python 2.7+ 和 3.5.2+ 中,允许酸洗 memoryview 对象。请尝试以下代码以确认:

import pickle

test = memoryview(b'abc')
test.__reduce__()

以上将引发以下错误:

Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
    File "/usr/lib/python2.7/copy_reg.py", line 70, in _reduce_ex
    raise TypeError, "can't pickle %s objects" % base.__name__
TypeError: can't pickle memoryview objects

显然,在 django-import-export(版本 0.6)的第 451 行中,BinaryField 作为 memoryview 对象传递给

original = deepcopy(instance)

导致错误的原因(instance 包含 BinaryField 作为 memoryview 对象)。
在当前版本 (1.0.0) 中,这发生在 446 行中。

模块的instance_loader检索/生成的实例不考虑BinaryField

您可能应该在django-import-export 开一张关于此的票。

【讨论】:

    【解决方案2】:

    也许传递实际数组而不是内存视图可以解决您的问题。如果你想并行执行一个函数,如果我没记错的话,它的所有参数都必须是可选的。至少python多处理就是这种情况。所以你可以将数组传递给函数并在你的函数中创建内存视图。

    参考:moreinfo

    【讨论】:

    • 嗯,我不会在任何地方传递内存视图。它可能是由 django-import-export 隐式完成的
    • 内存视图是在 BinaryFields.to_python 方法中创建的:github.com/django/django/blob/…> 链接来自当前头部,但行为已经有一段时间了。
    【解决方案3】:

    你在ABCModelForm 中添加了binary_field 吗?如果是,那么它正在产生问题,因为不可能在 ModelForm 中包含 BinaryField。供参考:binaryfield

    【讨论】:

    • 不,我在 ModelForm 的 Meta 类中有 exclude = ['binary_field']
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-06-12
    • 1970-01-01
    • 2021-01-12
    • 2022-07-18
    • 1970-01-01
    • 1970-01-01
    • 2015-12-05
    相关资源
    最近更新 更多