[英]Django Oracle integrity error when saving any instance to database
I'm doing a migration from sqlite to oracle backend. 我正在从sqlite迁移到oracle后端。 The oracle database already exists and is maintained by other people.
oracle数据库已经存在并由其他人维护。 Its version is Oracle9i Enterprise Edition Release 9.2.0.1.0.
其版本为Oracle9i Enterprise Edition版本9.2.0.1.0。
I have a simple model: 我有一个简单的模型:
class AliasType(models.Model):
id = models.AutoField(primary_key=True, db_column="F_ALIAS_ID")
name = models.CharField(u"Type name", max_length=255, unique=True, db_column="F_ALIAS_NAME")
class Meta:
db_table = "ALIAS"
./manage.py syncdb
does not return any errors. ./manage.py syncdb
不返回任何错误。 But when I try to create a new instance and save it to the database, I get the following error: 但是,当我尝试创建一个新实例并将其保存到数据库时,出现以下错误:
>>> AliasType.objects.create(name="test")
Traceback (most recent call last):
File "<console>", line 1, in <module>
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/manager.py", line 138, in create
return self.get_query_set().create(**kwargs)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/query.py", line 360, in create
obj.save(force_insert=True, using=self.db)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/base.py", line 460, in save
self.save_base(using=using, force_insert=force_insert, force_update=force_update)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/base.py", line 553, in save_base
result = manager._insert(values, return_id=update_pk, using=using)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/manager.py", line 195, in _insert
return insert_query(self.model, values, **kwargs)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/query.py", line 1435, in insert_query
return query.get_compiler(using=using).execute_sql(return_id)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/sql/compiler.py", line 791, in execute_sql
cursor = super(SQLInsertCompiler, self).execute_sql(None)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/models/sql/compiler.py", line 735, in execute_sql
cursor.execute(sql, params)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/backends/util.py", line 18, in execute
return self.cursor.execute(sql, params)
File "/mnt/Data/private/projects/envs/termary-oracle/src/django/django/db/backends/oracle/base.py", line 630, in execute
return self.cursor.execute(query, self._param_generator(params))
IntegrityError: ORA-01400: cannot insert NULL into ("SINCE"."ALIAS"."F_ALIAS_ID")
If I specify id, eg AliasType.objects.create(id=5, name="test")
, it works. 如果我指定id,例如
AliasType.objects.create(id=5, name="test")
,那么它可以工作。 I thought django should be able to retrieve id value automatically. 我认为django应该能够自动检索id值。 I've learnt that Oracle does not support autoincrement, and I should use triggers and sequences.
我了解到Oracle不支持自动增量,我应该使用触发器和序列。 I was told that there is an existing sequence in the database that returns ids for all new rows, and I know its name, say
SEQ_GET_NEW_ID
. 有人告诉我数据库中存在一个现有序列,该序列返回所有新行的ID,而且我知道它的名称,例如
SEQ_GET_NEW_ID
。
So the question is how to implement that in the most elegant way, ie how to tell Django to get id values for all new objects from the sequence named SEQ_GET_NEW_ID
without hacking it too much (eg overriding save() methods for all models)? 因此,问题是如何以最优雅的方式实现这一点,即如何告诉Django
get id values for all new objects from the sequence named SEQ_GET_NEW_ID
不会对其造成太大的get id values for all new objects from the sequence named SEQ_GET_NEW_ID
(例如,覆盖所有模型的save()方法)?
There is a ticket open ( #1946 ) to allow exactly that, overriding the default sequence name. 有一个打开的票证( #1946 )允许这样做,覆盖默认的序列名称。 But as it's not closed yet, I don't think there is a way without hacking.
但是由于它尚未关闭,我认为没有办法可以避免黑客入侵。
I haven't used Oracle before, but a quick search suggests that it is possible to create aliases/synonyms for sequences. 我以前没有使用过Oracle,但是快速搜索表明可以为序列创建别名/同义词。
manage.py sqlall <app>
should show you the sequence name Django is expecting. manage.py sqlall <app>
应该显示Django期望的序列名称。 So you probably could just make this an alias for SEQ_GET_NEW_ID
. 因此,您可能只是将其作为
SEQ_GET_NEW_ID
的别名。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.