Description

Some database backends (I've only tested postgresql, sqlite seems OK) seem to return a long PK instead of int when creating new model objects. When getting an existing model object, int is correctly returned. I did find a comment about this in the ​tutorial, but I don't think this is by design and I think this difference in behaviour between new and existing objects and database backends is buggy and violates the principle of least surprise.

It might be a bit of an edge case, but we were stumped for a while trying to figure out why created objects had a PK of a different type to existing objects. We initially noticed the problem because we use a pickle field to store various types of data -- PKs, dates and times, booleans, dicts, etc. -- and when passing in the value of a newly created PK to the pickle field we were then unable to filter on it unless we explicitly searched for long values.

So to work-around this issue we need to a) know the type of the PK that should be returned for existing objects and coerce it before passing to the pickle field if it does not match.

It looks good to me on sqlite and postgres, I don't have a test setup for other DBs, but given that it's just running the PK through the same output function that is being called on all other fields, it seems unlikely to cause issues.

I don't think this is worth it. Without a compelling case for why code should particularly care about the int/long difference, the extra complexity isn't needed. Numbers are numbers for almost all intents and purposes and who is writing code working with models that cares about the int versus long differentiation.

Should only be reopened with an example of non-trivial code that fails without this change. "I prefer it to be an integer" is not enough.

This ticket was accepted by a core dev. Work was done on a patch based on feedback received. Why is it now marked wontfix? The ticket description might be lacking a code example, and this might be an edge case, but this is a real world problem in a real project that had us stumped for a few hours.

"we use a pickle field to store various types of data -- PKs, dates and times, booleans, dicts, etc. -- and when passing in the value of a newly created PK to the pickle field we were then unable to filter on it unless we explicitly searched for long values."

Our PickleField.get_prep_value() method converts a python value passed to QuerySet.filter() (or .get(), etc.) into a pickle string so that we can filter on pickle fields. The pickle string for 1 is not the same as 1L, so our filter doesn't return the data we expect. To work-around this problem, we need to determine the type for primary key fields and coerce the value on newly created model objects explicitly in our code before pickling.

The primary key value returned by Model.objects.create() and Model.objects.get() should be the same. It seems to be a clear bug that the primary key value could be different types (and not the type specified in your model class), and I don't see any downside in making it so. How is it "not worth it" to fix? Do I need to include my implementation of PickleField in the tests?