Подтвердить что ты не робот

Страшная "не такая же ошибка объекта", пробирая объект queryset.query

У меня есть запрос, который мне нужно мариновать, и у меня возникают серьезные проблемы. cPickle.dumps(queryset.query) выдает следующую ошибку:

Can't pickle <class 'myproject.myapp.models.myfile.QuerySet'>: it not the same object as myproject.myapp.models.myfile.QuerySet

Странно (или, возможно, не так странно), я получаю эту ошибку только при вызове cPcikle из другого метода или представления, но не тогда, когда я вызываю его из командной строки.

Я сделал метод ниже, прочитав PicklingError: Невозможно pickle < class 'decimal.Decimal' > : это не тот же объект, что и decimal.Decimal и Django mod_wsgi PicklingError при сохранении объекта:

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)

Как вы можете видеть, я получаю очень отчаянный - этот метод по-прежнему дает ту же ошибку. Есть ли известное, не-хакерское решение этой проблемы?

EDIT: Пробовал использовать --noreload на сервере разработки django, но безрезультатно.

EDIT2: У меня была опечатка в ошибке, которую я отобразил выше - это был models.QuerySet, а не models.mymodel.QuerySet, о котором он жаловался. Здесь есть еще один нюанс, который заключается в том, что файл моих моделей разбит на несколько модулей, поэтому ошибка имеет значение ACTUALLY:

 Can't pickle <class 'myproject.myapp.models.myfile.QuerySet'>: it not the same object as myproject.myapp.models.myfile.QuerySet

Где myfile - один из модулей под моделями. У меня есть __ini__.py в моделях со следующей строкой:

from myfile import *

Интересно, влияет ли это на мою проблему. Есть ли способ изменить мой init, чтобы защитить себя от этого? Есть ли еще какие-нибудь тесты?

EDIT3: Ниже приведено несколько примеров моего использования: у меня есть модель под названием Context, которую я использую для заполнения элемента интерфейса экземплярами mymodel. Пользователь может добавлять/удалять/манипулировать объектами на стороне пользовательского интерфейса, изменять их контекст, а когда они возвращаются, они могут сохранять свои изменения, потому что контекст сериализовал все. Контекст имеет общий внешний ключ для разных типов фильтров/способов, которыми пользователь может манипулировать объектом, все из которых должны реализовывать несколько методов, которые контекст использует для определения того, что он должен отображать. Один из таких фильтров принимает запрос, который может быть передан и отображает все объекты в этом наборе запросов. Это позволяет передавать произвольные запросы, созданные в другом месте, и отображать их в элементе пользовательского интерфейса. Модель, использующая контекст, является иерархической (с использованием mptt для этого), а элемент пользовательского интерфейса делает запрос на получение дочерних элементов каждый раз, когда пользователь щелкает, мы можем потом взять детей и определить, должны ли они отображаться на основе того, они включены в контекст. Надеюсь, что это поможет!

EDIT4: Я могу сбрасывать пустой набор запросов, но как только я добавляю что-то полезное, он терпит неудачу.

EDIT4: Я на Django 1.2.3

4b9b3361

Ответ 1

Это может не случиться для всех, но я использовал ноутбук Ipython и имел аналогичную проблему, расчесывающую мой собственный класс. Проблема оказалась в вызове перезагрузки

from dir.my_module import my_class    
reload(dir.my_module)

Удаление вызова перезагрузки, а затем повторный запуск импорта и ячейки, где был создан экземпляр этого объекта, затем разрешено его мариновать.

Ответ 2

Происходит ли эта ошибка только с cPickle? Вы пробовали это со стандартным Pickle?

Есть другие модули, которые имеют сходную функциональность с Pickle/cPickle, например Gnosis Utilities "Pickle", который имеет преимущество генерации стандартного XML-вывода, используя модуль gnosis.xml.pickle. Я бы попробовал заменить cPickle другим модулем, чтобы убедиться, что у него такая же проблема, или если это может быть ошибкой в ​​реализации cPickle.

Ответ 3

не очень элегантный, но, возможно, он работает: добавьте каталог myfile -module в os.sys.path и используйте только import myfile в каждом модуле, где вы используете myfile. (удалите все from segment.segmentengine.models.segment import в любом месте вашего проекта)

Ответ 4

У меня есть аналогичная проблема, и она прерывистая.

PicklingError: Can't pickle <class 'decimal.Decimal'>: it not the same object as decimal.Decimal

Однако - я знаю, что я случайно удалил свой код, включая файлы .pyc, из старой установки, так что это, возможно, была моей проблемой. Сегодня я очистил свои старые .pyc файлы, и я жду, чтобы уйти от прерывистой проблемы.

Ответ 5

В соответствии с этим doc травление QuerySet не должно быть проблемой. Таким образом, проблема должна исходить из другого места.

Так как вы надумали:

EDIT2: у меня была опечатка в ошибке, которую я отобразил выше - это были модели. QuerySet, а не models.mymodel.QuerySet, о которых он жаловался. Здесь есть еще один нюанс, который заключается в том, что файл моих моделей разбит на несколько модулей, поэтому ошибка имеет значение ACTUALLY:

  • Второе сообщение об ошибке, похожее на предыдущее, похоже на то, что вы имеете в виду?
  • Сообщение об ошибке, которое вы указали, выглядит странно. Поскольку вы травляете "queryset.query", ошибка должна относиться к классу django.db.models.sql.Query вместо класса QuerySet.

Некоторые модули или классы могут иметь одно и то же имя. Они будут переопределять друг друга, а затем вызывать такую ​​проблему. Чтобы упростить задачу, я рекомендую вам использовать "import ooo.xxx" вместо "from ooo import *".

Ответ 6

Вы также можете попробовать

import ooo.xxx as othername