tickets: 1946
This data as json
id | created | changetime | last_pulled_from_trac | stage | status | component | type | severity | version | resolution | summary | description | owner | reporter | keywords | easy | has_patch | needs_better_patch | needs_tests | needs_docs | ui_ux |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
1946 | 2006-05-20 19:26:47 | 2011-04-20 17:55:49 | 2022-03-06 03:24:42.417640 | Accepted | closed | Database layer (models, ORM) | New feature | Normal | duplicate | Allow overriding of default sequence name | I wanted to be able to use Django's admin interface to edit PostgreSQL inherited tables. The normal use would be to have a single sequence on the parent table and let the children inherit that, so that the IDs across all children are unique. However, Django assumes that the sequence name is tablename_columnname_seq which does not apply in this case. I have created the folloiwing patch to allow one to override the default sequence name with one of your choosing by adding a seq_name= parameter when defining the field, like this: {{{ class PeerIAX(models.Model): class Admin: pass id = models.AutoField(primary_key=True, seq_name='asterisk_peer_id_seq') description = models.CharField(maxlength=255) hostname = models.CharField(maxlength=255) username = models.CharField(maxlength=255) secret = models.CharField(maxlength=255) def __str__(self): return description }}} In case it's not obvious, this simple patch does not add support to Django to actually *create* the tables. I hand-created them like so: {{{ CREATE TABLE asterisk_peer ( id SERIAL NOT NULL PRIMARY KEY, description VARCHAR(255) NOT NULL ); CREATE TABLE asterisk_peer_iax ( hostname VARCHAR(255) NOT NULL, username VARCHAR(255) NOT NULL, secret VARCHAR(255) NOT NULL ) INHERITS (asterisk_peer); }}} The patch is below. I abandon copyright on the code and you are welcome to incorporate the patch into Django as you see fit. {{{ diff -rduP ../Django-0.91-py2.3.egg.orig/django/db/backends/ado_mssql/base.py ./django/db/backends/ado_mssql/base.py --- ../Django-0.91-py2.3.egg.orig/django/db/backends/ado_mssql/base.py 2006-05-15 13:52:49.000000000 +0100 +++ ./django/db/backends/ado_mssql/base.py 2006-05-20 20:09:24.000000000 +0100 @@ -94,7 +94,9 @@ dictfetchmany = util.dictfetchmany dictfetchall = util.dictfetchall -def get_last_insert_id(cursor, table_name, pk_name): +def get_last_insert_id(cursor, table_name, pk_name, seq_name): + # FIXME: seq_name might be a useful thing to add to backends other than + # PostgreSQL cursor.execute("SELECT %s FROM %s WHERE %s = @@IDENTITY" % (pk_name, table_name, pk_name)) return cursor.fetchone()[0] diff -rduP ../Django-0.91-py2.3.egg.orig/django/db/backends/mysql/base.py ./django/db/backends/mysql/base.py --- ../Django-0.91-py2.3.egg.orig/django/db/backends/mysql/base.py 2006-05-15 13:52:49.000000000 +0100 +++ ./django/db/backends/mysql/base.py 2006-05-20 20:10:01.000000000 +0100 @@ -117,7 +117,9 @@ dictfetchmany = util.dictfetchmany dictfetchall = util.dictfetchall -def get_last_insert_id(cursor, table_name, pk_name): +def get_last_insert_id(cursor, table_name, pk_name, seq_name): + # FIXME: seq_name might be a useful thing to add to backends other than + # PostgreSQL return cursor.lastrowid def get_date_extract_sql(lookup_type, table_name): diff -rduP ../Django-0.91-py2.3.egg.orig/django/db/backends/postgresql/base.py ./django/db/backends/postgresql/base.py --- ../Django-0.91-py2.3.egg.orig/django/db/backends/postgresql/base.py 2006-05-15 13:52:49.000000000 +0100 +++ ./django/db/backends/postgresql/base.py 2006-05-20 19:40:12.000000000 +0100 @@ -75,8 +75,10 @@ "Returns all rows from a cursor as a dict" return cursor.dictfetchall() -def get_last_insert_id(cursor, table_name, pk_name): - cursor.execute("SELECT CURRVAL('\"%s_%s_seq\"')" % (table_name, pk_name)) +def get_last_insert_id(cursor, table_name, pk_name, seq_name): + if seq_name is None: + seq_name = "%s_%s_seq" % (table_name, pk_name) + cursor.execute("SELECT CURRVAL('\"%s\"')" % seq_name) return cursor.fetchone()[0] def get_date_extract_sql(lookup_type, table_name): diff -rduP ../Django-0.91-py2.3.egg.orig/django/db/backends/sqlite3/base.py ./django/db/backends/sqlite3/base.py --- ../Django-0.91-py2.3.egg.orig/django/db/backends/sqlite3/base.py 2006-05-15 13:52:49.000000000 +0100 +++ ./django/db/backends/sqlite3/base.py 2006-05-20 20:10:11.000000000 +0100 @@ -90,7 +90,9 @@ dictfetchmany = util.dictfetchmany dictfetchall = util.dictfetchall -def get_last_insert_id(cursor, table_name, pk_name): +def get_last_insert_id(cursor, table_name, pk_name, seq_name): + # FIXME: seq_name might be a useful thing to add to backends other than + # PostgreSQL return cursor.lastrowid def get_date_extract_sql(lookup_type, table_name): diff -rduP ../Django-0.91-py2.3.egg.orig/django/db/models/base.py ./django/db/models/base.py --- ../Django-0.91-py2.3.egg.orig/django/db/models/base.py 2006-05-15 13:52:49.000000000 +0100 +++ ./django/db/models/base.py 2006-05-20 19:55:52.000000000 +0100 @@ -187,7 +187,7 @@ (backend.quote_name(self._meta.db_table), ','.join(field_names), ','.join(placeholders)), db_values) if self._meta.has_auto_field and not pk_set: - setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column)) + setattr(self, self._meta.pk.attname, backend.get_last_insert_id(cursor, self._meta.db_table, self._meta.pk.column, self._meta.pk.seq_name)) transaction.commit_unless_managed() # Run any post-save hooks. diff -rduP ../Django-0.91-py2.3.egg.orig/django/db/models/fields/__init__.py ./django/db/models/fields/__init__.py --- ../Django-0.91-py2.3.egg.orig/django/db/models/fields/__init__.py 2006-05-15 13:52:49.000000000 +0100 +++ ./django/db/models/fields/__init__.py 2006-05-20 19:53:28.000000000 +0100 @@ -68,7 +68,7 @@ core=False, rel=None, default=NOT_PROVIDED, editable=True, prepopulate_from=None, unique_for_date=None, unique_for_month=None, unique_for_year=None, validator_list=None, choices=None, radio_admin=None, - help_text='', db_column=None): + help_text='', db_column=None,seq_name=None): self.name = name self.verbose_name = verbose_name self.primary_key = primary_key @@ -84,6 +84,7 @@ self.radio_admin = radio_admin self.help_text = help_text self.db_column = db_column + self.seq_name = seq_name # Set db_index to True if the field has a relationship and doesn't explicitly set db_index. self.db_index = db_index }}} | shmengie | abuse@cabal.org.uk | 0 | 1 | 1 | 1 | 1 | 0 |