Fixed #17713 -- Renamed BaseDatabaseFeatures.allows_primary_key_0 to allows_auto_pk_0.

MySQL does allow primary key with value 0. It only forbids autoincrement
primary key with value 0.

Thanks Claude Paroz for the report.
This commit is contained in:
Vajrasky Kok 2013-11-24 21:12:22 +08:00 committed by Tim Graham
parent b22d6c47a7
commit d3cf6cfacf
7 changed files with 16 additions and 12 deletions

View File

@ -613,8 +613,8 @@ class BaseDatabaseFeatures(object):
# Is there a 1000 item limit on query parameters? # Is there a 1000 item limit on query parameters?
supports_1000_query_parameters = True supports_1000_query_parameters = True
# Can an object have a primary key of 0? MySQL says No. # Can an object have an autoincrement primary key of 0? MySQL says No.
allows_primary_key_0 = True allows_auto_pk_0 = True
# Do we need to NULL a ForeignKey out, or can the constraint check be # Do we need to NULL a ForeignKey out, or can the constraint check be
# deferred # deferred

View File

@ -177,7 +177,7 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_date_lookup_using_string = False supports_date_lookup_using_string = False
supports_timezones = False supports_timezones = False
requires_explicit_null_ordering_when_grouping = True requires_explicit_null_ordering_when_grouping = True
allows_primary_key_0 = False allows_auto_pk_0 = False
uses_savepoints = True uses_savepoints = True
atomic_transactions = False atomic_transactions = False
supports_check_constraints = False supports_check_constraints = False

View File

@ -1010,6 +1010,12 @@ Miscellaneous
to ``False``). If you maintain a custom database backend, you should check to ``False``). If you maintain a custom database backend, you should check
that method. that method.
* The ``django.db.backends.BaseDatabaseFeatures.allows_primary_key_0``
attribute has been renamed to ``allows_auto_pk_0`` to better describe it.
It's ``True`` for all database backends included with Django except MySQL
which does allow primary keys with value 0. It only forbids *autoincrement*
primary keys with value 0.
.. _deprecated-features-1.7: .. _deprecated-features-1.7:
Features deprecated in 1.7 Features deprecated in 1.7

View File

@ -934,10 +934,9 @@ class ThreadTests(TestCase):
class MySQLPKZeroTests(TestCase): class MySQLPKZeroTests(TestCase):
""" """
Zero as id for AutoField should raise exception in MySQL, because MySQL Zero as id for AutoField should raise exception in MySQL, because MySQL
does not allow zero for automatic primary key. does not allow zero for autoincrement primary key.
""" """
@skipIfDBFeature('allows_auto_pk_0')
@skipIfDBFeature('allows_primary_key_0')
def test_zero_as_autoval(self): def test_zero_as_autoval(self):
with self.assertRaises(ValueError): with self.assertRaises(ValueError):
models.Square.objects.create(id=0, root=0, square=1) models.Square.objects.create(id=0, root=0, square=1)

View File

@ -70,13 +70,12 @@ class BulkCreateTests(TestCase):
"CA", "IL", "ME", "NY", "CA", "IL", "ME", "NY",
], attrgetter("two_letter_code")) ], attrgetter("two_letter_code"))
@skipIfDBFeature('allows_primary_key_0') @skipIfDBFeature('allows_auto_pk_0')
def test_zero_as_autoval(self): def test_zero_as_autoval(self):
""" """
Zero as id for AutoField should raise exception in MySQL, because MySQL Zero as id for AutoField should raise exception in MySQL, because MySQL
does not allow zero for automatic primary key. does not allow zero for automatic primary key.
""" """
valid_country = Country(name='Germany', iso_two_letter='DE') valid_country = Country(name='Germany', iso_two_letter='DE')
invalid_country = Country(id=0, name='Poland', iso_two_letter='PL') invalid_country = Country(id=0, name='Poland', iso_two_letter='PL')
with self.assertRaises(ValueError): with self.assertRaises(ValueError):

View File

@ -162,7 +162,7 @@ class InlineFormsetFactoryTest(TestCase):
Parent, Child, exclude=('school',), fk_name='mother' Parent, Child, exclude=('school',), fk_name='mother'
) )
@skipUnlessDBFeature('allows_primary_key_0') @skipUnlessDBFeature('allows_auto_pk_0')
def test_zero_primary_key(self): def test_zero_primary_key(self):
# Regression test for #21472 # Regression test for #21472
poet = Poet.objects.create(id=0, name='test') poet = Poet.objects.create(id=0, name='test')

View File

@ -389,10 +389,10 @@ if connection.features.interprets_empty_strings_as_nulls:
data[2]._meta.get_field('data').empty_strings_allowed and data[2]._meta.get_field('data').empty_strings_allowed and
data[3] is None)] data[3] is None)]
# Regression test for #8651 -- a FK to an object iwth PK of 0 # Regression test for #8651 -- a FK to an object with PK of 0
# This won't work on MySQL since it won't let you create an object # This won't work on MySQL since it won't let you create an object
# with a primary key of 0, # with an autoincrement primary key of 0,
if connection.features.allows_primary_key_0: if connection.features.allows_auto_pk_0:
test_data.extend([ test_data.extend([
(data_obj, 0, Anchor, "Anchor 0"), (data_obj, 0, Anchor, "Anchor 0"),
(fk_obj, 465, FKData, 0), (fk_obj, 465, FKData, 0),