问题描述
我正在尝试在“ manage.py dumpdata”命令中使用“自然键”进行序列化(docs):
python manage.py dumpdata --natural-primary --natural-foreign --indent 4 --format json --verbosity 1 > tests\test_fixtures\test_db2.json
当我在使用Project或Task模型(它们都必须设计)的其他应用上使用--natural-foreign时,出现以下错误:
CommandError: Unable to serialize database: Object of type Project is not JSON serializable
Exception ignored in: <generator object cursor_iter at 0x000001EF62481B48>
Traceback (most recent call last):
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\db\models\sql\compiler.py",line 1586,in cursor_iter
cursor.close()
sqlite3.ProgrammingError: Cannot operate on a closed database.
如果我只是从中转储数据,则“项目”应用程序可以运行,但是其他应用程序是使用与项目或任务相关的实体构建的,因此--natural-foreign选项将失败。
当模型(例如问问题)从Task要求一个natural_key,而其中从Project要求一个natural_key时,就会出现问题。
如果我使用Pycharm Python控制台访问项目或任务的查询集(此处为“ q”),则可以使用:
serializers.serialize('json',q,indent=2,use_natural_foreign_keys=True,use_natural_primary_keys=True)
但是,如果“ w”是来自另一个具有Task外键的应用程序中的Question对象的列表,则会出现此错误:
Traceback (most recent call last):
File "<input>",line 1,in <module>
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\__init__.py",line 128,in serialize
s.serialize(queryset,**options)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\base.py",line 115,in serialize
self.end_object(obj)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\json.py",line 53,in end_object
json.dump(self.get_dump_object(obj),self.stream,**self.json_kwargs)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\__init__.py",line 179,in dump
for chunk in iterable:
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py",line 431,in _iterencode
yield from _iterencode_dict(o,_current_indent_level)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py",line 405,in _iterencode_dict
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py",line 325,in _iterencode_list
yield from chunks
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py",line 438,in _iterencode
o = _default(o)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\site-packages\django\core\serializers\json.py",line 104,in default
return super().default(o)
File "C:\Users\Andrew\anaconda3\envs\Acejet_development\lib\json\encoder.py",in default
raise TypeError(f'Object of type {o.__class__.__name__} '
TypeError: Object of type Project is not JSON serializable
模型是:
# projects.models.py
class BaseModelWithHistory(models.Model):
history = HistoricalRecords(inherit=True)
natural_key_fields = ('id',) # default
class Meta:
abstract = True
def natural_key(self):
fieldlist = [getattr(self,fieldname) for fieldname in self.natural_key_fields]
return tuple(fieldlist)
# natural_key.dependencies = ['projects.Project','projects.Task'] # serialize these first.
class Project(BaseModelWithHistory):
"""
'Projects' group Tasks.
"""
project_name = models.CharField(max_length=200,default="development_project")
project_short_description = models.CharField(
max_length=500,default="This is the default text.")
target_group = models.ManyToManyField(Group,blank=True)
objects = ProjectDiscreteManager()
natural_key_fields = ('project_name',)
class Task(BaseModelWithHistory):
number = models.PositiveIntegerField(default=0)
name = models.CharField(max_length=200,default='new task')
project = models.ForeignKey(Project,on_delete=models.CASCADE)
target_group = models.ManyToManyField(Group,blank=True)
app_label = models.CharField(max_length=80,choices=app_choices(),null=True,blank=True)
objects = discrete_manager_factory('project')
natural_key_fields = ('project','name','number')
我没想到会导致此问题,但我肯定是错的:
- 由Discrete_manager_factory()创建的ProjectDiscreteManager和其他对象的行为与默认管理器(models.Manager())完全相同,除非通过已标识用户的请求进行调用,在这种情况下,它将添加一个过滤器以查看该用户是否为在小组中。
- 所有模型都定义了natural_keys元组,因为父类将其定义为('id',);大多数模型都用更具代表性的字段覆盖了这一点。
- 为所有模型设置了natural_key.dependencies列表以对Project和Task进行优先排序,对于其他所有模型,我都会收到“无法解析依赖项”错误。我认为this ticket与之相关,但是不确定如何跟踪此修复程序是否已经在我使用的Django 3.0.6中,我应该将其调直并正确飞行,或者如果我的Han Solo'这应该wooork'将很快获得奖励。 [更新:我确定它会在Django 3.1.1中提供,但我不确定它是否会解决我为自己创建的“无法解决依赖关系”错误。]
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)