Created
November 2, 2012 10:31
-
-
Save haoch/4000035 to your computer and use it in GitHub Desktop.
django pull id from oracle sequence id
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
''' 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') |
How can i implement Test for this? The problem: my test Database is a sqlite3 !
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
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))