Skip to content

Instantly share code, notes, and snippets.

@haoch
Created November 2, 2012 10:31
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save haoch/4000035 to your computer and use it in GitHub Desktop.
Save haoch/4000035 to your computer and use it in GitHub Desktop.
django pull id from oracle sequence id
''' Django ORM don't support to pull id from sequence by default.'''
def update_id(func):
'''A decorator for pulling a data object's ID value out of a
user-defined sequence. This gets around a limitation in
django whereby we cannot supply our own sequence names.'''
def decorated_function(*args):
# Grab a reference to the data object we want to update.
data_object = args[0]
# Only update the ID if there isn't one yet.
if data_object.id is None:
# Construct the new sequence name based on the table's meta data.
sequence_name = 'pk_%s' % data_object._meta.db_table
# Query the database for the next sequence value.
from django.db import connection
cursor = connection.cursor()
cursor.execute("SELECT nextval(%s)", [sequence_name])
row = cursor.fetchone()
# Update the data object's ID with the returned sequence value.
data_object.id = row[0]
# Execute the function we're decorating.
return func(*args)
return decorated_function
# Example model using the decorator to grab the ID. Note that the ID
# is a regular integer field and that it is not displayed in the admin.
class FAQ(models.Model):
id = models.IntegerField(primary_key=True)
category = models.ForeignKey(FAQCategory)
question = models.CharField(maxlength=255)
answer = models.TextField()
published = models.BooleanField(default=False)
list_ordering = models.FloatField(max_digits=6, decimal_places=2, default=9999)
def __str__(self):
return self.question
@update_id
def save(self):
# Now actually save the object.
super(FAQ, self).save()
class Meta:
db_table = 'faqs'
class Admin:
fields = (
(None, {'fields': ('category', 'question', 'answer', 'published', 'list_ordering')}),
)
list_display = ('question', 'category', 'list_ordering')
@JccSanabria
Copy link

JccSanabria commented Jun 13, 2017

Your solution is pretty nice, but nextval is not a default function in Oracle (11g XE) so it didnt work for me. I suggest to modify line 20 as

cursor.execute("SELECT {sequence_name}.nextval from dual".format(sequence_name=sequence_name))

@limberger
Copy link

How can i implement Test for this? The problem: my test Database is a sqlite3 !

@limberger
Copy link

How can i implement Test for this? The problem: my test Database is a sqlite3 !

In the tests i'll generate a random number!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment