[2.0.x] Fixed #27979 -- Made MySQL raise IntegrityError rather than OperationalError when saving negative numbers in PositiveInteger fields.

Backport of dd82f33271 from master
This commit is contained in:
Tim Graham 2017-09-29 14:50:51 -04:00
parent eff5f837c9
commit d6cec5f6ff
2 changed files with 14 additions and 2 deletions

View File

@ -57,7 +57,10 @@ class CursorWrapper:
Implemented as a wrapper, rather than a subclass, so that it isn't stuck Implemented as a wrapper, rather than a subclass, so that it isn't stuck
to the particular underlying representation returned by Connection.cursor(). to the particular underlying representation returned by Connection.cursor().
""" """
codes_for_integrityerror = (1048,) codes_for_integrityerror = (
1048, # Column cannot be null
1690, # BIGINT UNSIGNED value is out of range
)
def __init__(self, cursor): def __init__(self, cursor):
self.cursor = cursor self.cursor = cursor

View File

@ -1,6 +1,8 @@
import unittest
from django.core import validators from django.core import validators
from django.core.exceptions import ValidationError from django.core.exceptions import ValidationError
from django.db import connection, models from django.db import IntegrityError, connection, models
from django.test import SimpleTestCase, TestCase from django.test import SimpleTestCase, TestCase
from .models import ( from .models import (
@ -151,6 +153,13 @@ class PositiveIntegerFieldTests(IntegerFieldTests):
model = PositiveIntegerModel model = PositiveIntegerModel
documented_range = (0, 2147483647) documented_range = (0, 2147483647)
@unittest.skipIf(connection.vendor == 'sqlite', "SQLite doesn't have a constraint.")
def test_negative_values(self):
p = PositiveIntegerModel.objects.create(value=0)
p.value = models.F('value') - 1
with self.assertRaises(IntegrityError):
p.save()
class ValidationTests(SimpleTestCase): class ValidationTests(SimpleTestCase):