26đź‘Ť
Even if you can query the next available primary key value, it wouldn’t help you. Unless you lock the table, you can’t use that value before some other database client might grab it for their insert.
Instead, you should just insert your row, and then you can query the most recent key value generated during your current session. Every database that supports auto-generated primary keys provides a method to retrieve the most recent key inserted during your session.
The “during your session” part is important because it shields your session from any inserts being done concurrently by other clients. They can generate key values and your session will continue to report the same value it inserted most recently.
@Stuart Childs supposes that MySQL generates the next ID with MAX(column_name)+1
but this is incorrect. Say you insert a row and an ID value is generated. But you rollback this insert, or subsequently DELETE
that row. The next time you insert, MySQL will generate a brand new ID value. So the ID value is one greater than the last ID value generated by any client, regardless of what rows are currently stored in the table.
Likewise if you insert but don’t commit immediately. Before you commit, some other client does an insert. Both your session and the other client’s session will have their own unique ID value generated. Auto-generated primary keys operate without regard to transaction isolation, to ensure uniqueness.
Auto-generated primary key values are not re-used or allocated to more than one session, even if you have not yet committed your insert, or if you rollback the insert, or if you delete the row.
- Overridding Django Admin's object-tools bar for one Model
- Django: I get a [relation "auth_group" does not exist] error after syncdb
- No connection could be made because the target machine actively refused it (Django)
- Google.maps.event.addDomListener() is deprecated, use the standard addEventListener() method instead : Google Place autocomplete Error
- Django forms give: Select a valid choice. That choice is not one of the available choices
1đź‘Ť
next_id = User.objects.order_by('-id').first().id + 1
Might need to handle if none exists.
Or with a max query:
from django.db.models import Max
users = User.objects.all()
#might be possible model has no records so make sure to handle None
next_id = users.aggregate(Max('id'))['id__max'] + 1 if users else 1
- Overriding Size of Django Admin Multi-select Widget
- Django RelatedObjectDoesNotExist error
- Django Postgres ArrayField vs One-to-Many relationship
- How to access RequestContext in class-based generic views?
0đź‘Ť
I think you’ll have to execute some custom SQL. The SQL you need will be DB specific. As far as I know, there is no reliable way to do this in MySQL. You can get the last insert ID but it is session specific (i.e. you can get the ID of the last record you inserted in your DB session but not the last ID for another session which may have happened after yours). However (and someone correct me if I’m wrong), MySQL generates the next ID with MAX(column_name) + 1 so you could do the same.
PostgreSQL makes it a lot easier with its sequence manipulation functions.
Edit:
Turns out I was thinking of AUTO_INCREMENT
columns within a multi-column key which are generated with MAX(column_name)+1. However, the point still stands that there is no way to retrieve the next ID before it is generated by an insert, which was the original question.
- Restricting all the views to authenticated users in Django
- How do I extend UserCreationForm to include email field
- Override serializer.data in Django REST Framework
- Problem launching docker-compose : python modules not installed
- How to update a cookie in Django
0đź‘Ť
I had this same question because I was duplicating an element and I wanted to change its pk to a new one to be able to insert it.
My solution was as follows:
import copy
objectCopy=copy.copy(object)
objectCopy.pk=None
objectCopy.save()
I mean, if save()
does it for you, why would you want to do it manually?
- How can I get all the objects in a Django model that have a specific value for a ForeignKey field?
- Django.db.models.loading.get_model vs. importing