我有一个带有oracle后端的django项目,我正在尝试将现有数据迁移到新服务器。我通常使用Postgresql,对oracle怪癖的了解有限。
运行django 2.2和python 3.8
我已经使用python manage.py dumpdata > allmydata.json
导出了数据,没有任何问题。
当我使用python manage.py loaddata allmydata.json
加载数据时,我会得到以下错误。
ORA-24816: Expanded non LONG bind data supplied after actual LONG or LOB column
在我遇到这个错误之前,大约有一半的数据加载。我的理解是,我的所有LOB列都应该是sql查询的末尾。
我的问题是,对于加载数据和正常操作,我如何做到这一点?有没有一种方法可以强制Django ORM以特定的方式构造查询?如果我更改模型中字段定义的顺序,会这样做吗?我正在加载的数据库是干净的,所以如果需要,我可以删除所有内容。
为了澄清,我可以从站点和负载数据中触发相同的问题。问题似乎是生成的SQL无法说明LOB CLOB类型的列,NCLOB需要位于插入语句的末尾。
那么,如何控制字段在ORM生成的insert语句中出现的顺序呢。
经过大量的挖掘和实验,我确定了以下内容:
给定一个类似的模型
class Experiment(models.Model):
experiment_id = models.CharField(max_length=150, unique=True)
name = models.CharField(max_length=100, blank=True, null=True)
source_application = models.CharField(max_length=100, blank=True, null=True)
par_id = models.CharField(max_length=50, blank=True, null=True)
experiment_information = RichTextUploadingField(blank=True)
conclusion = RichTextUploadingField(blank=True)
experiment_creator = models.CharField(blank=True, null=True, max_length=100)
experiment_target = RichTextField(blank=True)
project_lead = models.CharField(max_length=100, blank=True, null=True)
experiment_path = models.CharField(max_length=200, blank=True, null=True)
project = models.CharField(max_length=200, blank=True, null=True)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
alt_eln_id = models.CharField(max_length=20, blank=True, null=True)
need_witness = models.BooleanField(blank=True, null=True)
将生成插入查询,如:
('INSERT INTO "MPD_EXPERIMENT" ("EXPERIMENT_ID", "NAME", "SOURCE_APPLICATION", '
'"PAR_ID", "EXPERIMENT_INFORMATION", "CONCLUSION", "EXPERIMENT_CREATOR", '
'"EXPERIMENT_TARGET", "PROJECT_LEAD", "EXPERIMENT_PATH", "PROJECT", '
'"START_DATE", "END_DATE", "ALT_ELN_ID", "NEED_WITNESS") VALUES (%s, %s, %s, '
'%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING '
'"MPD_EXPERIMENT"."ID" INTO %s')
因此,为了解决ORA-24816
问题,我只需要更改模型中字段定义的顺序。在这种情况下,我需要将所有RichTextUploadingFields移到模型声明的末尾。
class Experiment(models.Model):
experiment_id = models.CharField(max_length=150, unique=True)
name = models.CharField(max_length=100, blank=True, null=True)
source_application = models.CharField(max_length=100, blank=True, null=True)
par_id = models.CharField(max_length=50, blank=True, null=True)
experiment_creator = models.CharField(blank=True, null=True, max_length=100)
project_lead = models.CharField(max_length=100, blank=True, null=True)
experiment_path = models.CharField(max_length=200, blank=True, null=True)
project = models.CharField(max_length=200, blank=True, null=True)
start_date = models.DateField(blank=True, null=True)
end_date = models.DateField(blank=True, null=True)
alt_eln_id = models.CharField(max_length=20, blank=True, null=True)
need_witness = models.BooleanField(blank=True, null=True)
experiment_information = RichTextUploadingField(blank=True)
conclusion = RichTextUploadingField(blank=True)
experiment_target = RichTextField(blank=True)