Skip to content

Commit

Permalink
Fixed #5218: Made Oracle create autoinc triggers using the correct name
Browse files Browse the repository at this point in the history
of the AutoField column rather than always assume "ID".


git-svn-id: http://code.djangoproject.com/svn/django/trunk@6195 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information
nightflyerkilo committed Sep 14, 2007
1 parent 933cda3 commit 93f6016
Show file tree
Hide file tree
Showing 6 changed files with 20 additions and 10 deletions.
5 changes: 3 additions & 2 deletions django/core/management/sql.py
Expand Up @@ -302,7 +302,8 @@ def sql_model_create(model, style, known_models=set()):


if opts.has_auto_field: if opts.has_auto_field:
# Add any extra SQL needed to support auto-incrementing primary keys. # Add any extra SQL needed to support auto-incrementing primary keys.
autoinc_sql = connection.ops.autoinc_sql(opts.db_table) auto_column = opts.auto_field.db_column or opts.auto_field.name
autoinc_sql = connection.ops.autoinc_sql(opts.db_table, auto_column)
if autoinc_sql: if autoinc_sql:
for stmt in autoinc_sql: for stmt in autoinc_sql:
final_output.append(stmt) final_output.append(stmt)
Expand Down Expand Up @@ -385,7 +386,7 @@ def many_to_many_sql_for_model(model, style):
final_output.append('\n'.join(table_output)) final_output.append('\n'.join(table_output))


# Add any extra SQL needed to support auto-incrementing PKs # Add any extra SQL needed to support auto-incrementing PKs
autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table()) autoinc_sql = connection.ops.autoinc_sql(f.m2m_db_table(), 'id')
if autoinc_sql: if autoinc_sql:
for stmt in autoinc_sql: for stmt in autoinc_sql:
final_output.append(stmt) final_output.append(stmt)
Expand Down
2 changes: 1 addition & 1 deletion django/db/backends/__init__.py
Expand Up @@ -56,7 +56,7 @@ class BaseDatabaseOperations(object):
a backend performs ordering or calculates the ID of a recently-inserted a backend performs ordering or calculates the ID of a recently-inserted
row. row.
""" """
def autoinc_sql(self, table): def autoinc_sql(self, table, column):
""" """
Returns any SQL needed to support auto-incrementing primary keys, or Returns any SQL needed to support auto-incrementing primary keys, or
None if no SQL is necessary. None if no SQL is necessary.
Expand Down
15 changes: 9 additions & 6 deletions django/db/backends/oracle/base.py
Expand Up @@ -31,20 +31,23 @@ class DatabaseFeatures(BaseDatabaseFeatures):
uses_custom_queryset = True uses_custom_queryset = True


class DatabaseOperations(BaseDatabaseOperations): class DatabaseOperations(BaseDatabaseOperations):
def autoinc_sql(self, table): def autoinc_sql(self, table, column):
# To simulate auto-incrementing primary keys in Oracle, we have to # To simulate auto-incrementing primary keys in Oracle, we have to
# create a sequence and a trigger. # create a sequence and a trigger.
sq_name = get_sequence_name(table) sq_name = get_sequence_name(table)
tr_name = get_trigger_name(table) tr_name = get_trigger_name(table)
tbl_name = self.quote_name(table)
col_name = self.quote_name(column)
sequence_sql = 'CREATE SEQUENCE %s;' % sq_name sequence_sql = 'CREATE SEQUENCE %s;' % sq_name
trigger_sql = """ trigger_sql = """
CREATE OR REPLACE TRIGGER %s CREATE OR REPLACE TRIGGER %(tr_name)s
BEFORE INSERT ON %s BEFORE INSERT ON %(tbl_name)s
FOR EACH ROW FOR EACH ROW
WHEN (new.id IS NULL) WHEN (new.%(col_name)s IS NULL)
BEGIN BEGIN
SELECT %s.nextval INTO :new.id FROM dual; SELECT %(sq_name)s.nextval
END;/""" % (tr_name, self.quote_name(table), sq_name) INTO :new.%(col_name)s FROM dual;
END;/""" % locals()
return sequence_sql, trigger_sql return sequence_sql, trigger_sql


def date_extract_sql(self, lookup_type, field_name): def date_extract_sql(self, lookup_type, field_name):
Expand Down
1 change: 1 addition & 0 deletions django/db/models/fields/__init__.py
Expand Up @@ -433,6 +433,7 @@ def contribute_to_class(self, cls, name):
assert not cls._meta.has_auto_field, "A model can't have more than one AutoField." assert not cls._meta.has_auto_field, "A model can't have more than one AutoField."
super(AutoField, self).contribute_to_class(cls, name) super(AutoField, self).contribute_to_class(cls, name)
cls._meta.has_auto_field = True cls._meta.has_auto_field = True
cls._meta.auto_field = self


def formfield(self, **kwargs): def formfield(self, **kwargs):
return None return None
Expand Down
2 changes: 1 addition & 1 deletion django/db/models/options.py
Expand Up @@ -33,7 +33,7 @@ def __init__(self, meta):
self.admin = None self.admin = None
self.meta = meta self.meta = meta
self.pk = None self.pk = None
self.has_auto_field = False self.has_auto_field, self.auto_field = False, None
self.one_to_one_field = None self.one_to_one_field = None
self.parents = [] self.parents = []


Expand Down
5 changes: 5 additions & 0 deletions tests/regressiontests/model_regress/models.py
Expand Up @@ -20,6 +20,11 @@ class Meta:
def __unicode__(self): def __unicode__(self):
return self.headline return self.headline


class Movie(models.Model):
#5218: Test models with non-default primary keys / AutoFields
movie_id = models.AutoField(primary_key=True)
name = models.CharField(max_length=60)

__test__ = {'API_TESTS': """ __test__ = {'API_TESTS': """
(NOTE: Part of the regression test here is merely parsing the model (NOTE: Part of the regression test here is merely parsing the model
declaration. The verbose_name, in particular, did not always work.) declaration. The verbose_name, in particular, did not always work.)
Expand Down

0 comments on commit 93f6016

Please sign in to comment.