简体   繁体   English

将任何实例保存到数据库时,Django Oracle完整性错误

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM