Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bug/Feature: Allow updating primary key of an object #1870

Open
merlinz01 opened this issue Feb 4, 2025 · 4 comments · May be fixed by #1873
Open

Bug/Feature: Allow updating primary key of an object #1870

merlinz01 opened this issue Feb 4, 2025 · 4 comments · May be fixed by #1873

Comments

@merlinz01
Copy link

Describe the bug
If I do this:

user.id = 123
await user.save(update_fields=['id'])

the operation fails with a database error:

asyncpg.exceptions._base.InterfaceError: the server expects 0 arguments for this query, 1 was passed
HINT:  Check the query against the passed list of arguments.  Note that parameters are supported only in SELECT, INSERT, UPDATE, DELETE, MERGE and VALUES statements, and will *not* work in statements  like CREATE VIEW or DECLARE CURSOR.

To Reproduce
See above.

Expected behavior
The object's primary key should be updated.

Additional context
This if-statement

if not self.model._meta.fields_map[field].pk:

removes the id from the update field list, and this results in an empty SQL statement being generated.

I can update the primary key with hand-written SQL just fine.

@waketzheng waketzheng linked a pull request Feb 5, 2025 that will close this issue
7 tasks
@waketzheng
Copy link
Contributor

waketzheng commented Feb 5, 2025

I believe that you should use User.create instead of update_fields=['id'], e.g.:

user.id = 123
new_user = await user.create(**dict(user))

@merlinz01
Copy link
Author

That would work in most cases, but the idea is to be able to change the ID while preserving all the other data, not to delete and re-create. The SQL would look like this: UPDATE users SET id=123 WHERE id=100.

I suppose this could break foreign-key references to the updated object. Also I'm not needing to do this in my code after all, so it's not high priority. At least we should get a nicer error message, which I see @waketzheng is doing.

@henadzit
Copy link
Contributor

henadzit commented Feb 5, 2025

That would work in most cases, but the idea is to be able to change the ID while preserving all the other data, not to delete and re-create. The SQL would look like this: UPDATE users SET id=123 WHERE id=100.

i don't think it is valid to update primary keys. For instance, when changing the id of an object, Django creates a copy of the object with the new id. However, I think it's better to raise an error in this case and force the user to actually create a new object if they want to have a duplicate. It is less error prone and seems more correct.

@merlinz01
Copy link
Author

Makes sense to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants