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
Fixed #27452 -- Added serial fields to contrib.postgres. #18123
base: main
Are you sure you want to change the base?
Conversation
65d6140
to
fd0e9b4
Compare
e892da4
to
97cbc23
Compare
fccac26
to
2b48193
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a great start!
In addition to the specific comments I added, we'll need some migrations tests to cover adding/removing serial fields and converting between serial and auto fields.
tests/schema/tests.py
Outdated
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_serial_to_integer(self): | ||
from django.contrib.postgres.fields import SerialField | ||
|
||
self.serial_to_integer_test(SerialField, IntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_serial_to_small_integer(self): | ||
from django.contrib.postgres.fields import SerialField | ||
|
||
self.serial_to_integer_test(SerialField, SmallIntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_serial_to_big_integer(self): | ||
from django.contrib.postgres.fields import SerialField | ||
|
||
self.serial_to_integer_test(SerialField, BigIntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_small_serial_to_integer(self): | ||
from django.contrib.postgres.fields import SmallSerialField | ||
|
||
self.serial_to_integer_test(SmallSerialField, IntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_small_serial_to_small_integer(self): | ||
from django.contrib.postgres.fields import SmallSerialField | ||
|
||
self.serial_to_integer_test(SmallSerialField, SmallIntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_small_serial_to_big_integer(self): | ||
from django.contrib.postgres.fields import SmallSerialField | ||
|
||
self.serial_to_integer_test(SmallSerialField, BigIntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_big_serial_to_big_integer(self): | ||
from django.contrib.postgres.fields import BigSerialField | ||
|
||
self.serial_to_integer_test(BigSerialField, BigIntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_big_serial_to_integer(self): | ||
from django.contrib.postgres.fields import BigSerialField | ||
|
||
self.serial_to_integer_test(BigSerialField, IntegerField) | ||
|
||
@unittest.skipUnless(connection.vendor == "postgresql", "PostgreSQL specific") | ||
@isolate_apps("schema") | ||
@tag("serial") | ||
def test_big_serial_to_small_integer(self): | ||
from django.contrib.postgres.fields import BigSerialField | ||
|
||
self.serial_to_integer_test(BigSerialField, SmallIntegerField) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This feels like a good use case for subTest
to me.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, the issue is we would either need to generate the test models with a dynamic name, or clean up the test models after the subtests - IMO it's more trouble than worth it.
e7fdd21
to
8052e52
Compare
@LilyFoote , thanks for the review! Could you point me to some tests I could copy to get started? I'm not sure how to test the migrations other than with the |
8052e52
to
42c53c4
Compare
For database defaults I added tests in tests/migrations/test_autodetector.py and tests/migrations/test_operations.py. |
569c960
to
0ebc30b
Compare
0fc425d
to
d4f4219
Compare
4c086eb
to
51ed545
Compare
I have managed to test these operations (add, alter, remove serial field) in the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We will need to address the backward compatibility with pre-Django 4.1 AutoField
on PostgreSQL to avoid breaking many old projects that didn't manually migrate to identity columns.
Edit: This might not be too much of a problem after all, but we should carefully consider all the places where things could break, e.g. migrations. We should likely have a test that starts out with a pre-Django 4.1 AutoField
to make sure that it is handled correctly.
@ngnpope , thank you for reviewing my changes ! 🙏 I have pushed a fix for the issues you mentioned. |
@ngnpope , I think all concerns has been addressed, let me know what you think. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm loving the progress you've made here. I have a few minor suggestions, but overall looks good to me!
Thanks a lot @LilyFoote ! I addressed your suggestions. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @csirmazbendeguz
I haven't reviewed this in depth but will hope to review again soon, as a first look through, this looks nice
if self.null: | ||
return [ | ||
checks.Error( | ||
"SerialFields do not accept null values.", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"SerialFields do not accept null values.", | |
f"{self.__class__.__name__} must not have ``null=True``.", |
Saying "must not have null=True
" aligns more to fields.E007
.
Also this is currently documented as
``<field>`` does not accept null values.
But always says SerialFields
, maybe we should do something similar to fields.E010
and update the error message depending on the field. If so, update each of these, otherwise I would document the check to be:
SerialFields does not accept null values.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sarahboyce , I was following fields.E110
which has:
``BooleanField``\s do not accept null values
It was @ngnpope 's idea to make this error message general, and I agree with it, because this way we wouldn't need to define a new error code every time a new field doesn't accept a null
value.
If you would like to make this specific to serial fields, I believe we should choose a different error code.
I agree with using the class name instead of "SerialFields" - I adjusted it.
e84d15f
to
0ec1583
Compare
0ec1583
to
d04ee2c
Compare
Thanks a lot @sarahboyce , I addressed your comments, let me know what you think. |
Trac ticket number
ticket-27452
Branch description
Added
SmallSerialField
,SerialField
,BigSerialField
tocontrib.postgres
.Previous PR
Checklist
main
branch.