我有一个查询集,我需要懒惰地腌制,我有一些严重的麻烦。 cPickle.dumps(queryset.query)
会抛出以下错误:
Can't pickle <class 'myproject.myapp.models.myfile.QuerySet'>: it's not the same object as myproject.myapp.models.myfile.QuerySet
奇怪(或者可能不那么奇怪),当我从另一个方法或视图中调用cPcikle
时,我只会遇到错误,但是当我从命令行调用它时却没有。
我在阅读PicklingError: Can't pickle <class 'decimal.Decimal'>: it's not the same object as decimal.Decimal和Django mod_wsgi PicklingError while saving object之后制作了以下方法:
def dump_queryset(queryset, model):
from segment.segmentengine.models.segment import QuerySet
memo = {}
new_queryset = deepcopy(queryset, memo)
memo = {}
new_query = deepcopy(new_queryset.query, memo)
queryset = QuerySet(model=model, query=new_query)
return cPickle.dumps(queryset.query)
正如您所看到的,我非常绝望 - 该方法仍会产生相同的错误。是否有一个已知的,非hacky解决这个问题的方法?
编辑:尝试使用在django开发服务器上运行的--noreload
,但无济于事。
EDIT2:我在上面显示的错误中输了一个错误 - 它是models.QuerySet
,而不是models.mymodel.QuerySet
它正在抱怨。这里有另一个细微差别,就是我的模型文件分为多个模块,因此错误实际上是:
Can't pickle <class 'myproject.myapp.models.myfile.QuerySet'>: it's not the same object as myproject.myapp.models.myfile.QuerySet
其中myfile是模型下的模块之一。我在模型中有一个__ini__.py
,其中包含以下行:
from myfile import *
我想知道这是否有助于解决我的问题。有没有办法改变我的init
来保护自己免受这种伤害?还有其他测试吗?
EDIT3:以下是关于我的用例的更多背景知识:我有一个名为Context
的模型,我用它来填充mymodel
实例的UI元素。用户可以在UI端添加/删除/操作对象,更改其上下文,当他们返回时,他们可以保留他们的更改,因为上下文序列化了所有内容。上下文具有用于操作对象的不同类型的过滤器/方式的通用外键,所有这些都必须实现上下文用于确定应显示的内容的一些方法。一个这样的过滤器采用可以传入的查询集并显示该查询集中的所有对象。这提供了一种传递在其他地方生成的任意查询集并将它们显示在UI元素中的方法。使用Context的模型是分层的(对此使用mptt),并且UI元素在每次用户点击时发出请求以获取子项,然后我们可以带孩子并根据是否应该根据是否显示它们来显示它们包含在上下文中。希望有所帮助!
EDIT4:我可以转储一个空的查询集,但只要我添加了任何值,就会失败。
EDIT4:我在Django 1.2.3上
答案 0 :(得分:4)
对于每个人来说情况可能并非如此,但我使用的是Ipython笔记本,并且在我自己的课程中遇到了类似的问题。 结果问题来自重载调用
dict
删除重新加载调用,然后重新运行导入以及创建该对象实例的单元格,然后允许对其进行pickle。
答案 1 :(得分:1)
不那么优雅,但也许它有效:
将myfile
模块的目录添加到os.sys.path
,并在您使用import myfile
的每个模块中仅使用myfile
。 (删除项目中任何位置的任何from segment.segmentengine.models.segment import
)
答案 2 :(得分:0)
根据这个doc,挑选一个QuerySet应该不是问题。因此,问题应该来自其他地方。
自从你想到了:
EDIT2:我在上面显示的错误中输入了一个拼写错误 - 它是models.QuerySet,而不是models.mymodel.QuerySet,它正在抱怨。这里有另一个细微差别,就是我的模型文件分为多个模块,因此错误实际上是:
某些模块或类可能具有相同的名称。他们会互相覆盖然后引起这种问题。为了方便起见,我建议您使用“import ooo.xxx”而不是“from ooo import *”。
答案 3 :(得分:0)
您也可以尝试
import ooo.xxx as othername