summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTim Graham <timograham@gmail.com>2018-06-22 14:42:51 -0400
committerTim Graham <timograham@gmail.com>2018-06-25 14:01:04 -0400
commitb9cf764be62e77b4777b3a75ec256f6209a57671 (patch)
treed4eb2e5cc340316fa277528044ee35d1ac473dc5
parent741061852851d6aff8e35f46b0e165685d3e79e0 (diff)
Fixed #29517 -- Added support for SQLite column check constraints on positive integer fields.
-rw-r--r--django/db/backends/sqlite3/base.py4
-rw-r--r--django/db/backends/sqlite3/features.py1
-rw-r--r--django/db/backends/sqlite3/introspection.py26
-rw-r--r--docs/releases/2.2.txt5
4 files changed, 34 insertions, 2 deletions
diff --git a/django/db/backends/sqlite3/base.py b/django/db/backends/sqlite3/base.py
index b644f4d42a..6237c3b6f8 100644
--- a/django/db/backends/sqlite3/base.py
+++ b/django/db/backends/sqlite3/base.py
@@ -76,6 +76,10 @@ class DatabaseWrapper(BaseDatabaseWrapper):
'TimeField': 'time',
'UUIDField': 'char(32)',
}
+ data_type_check_constraints = {
+ 'PositiveIntegerField': '"%(column)s" >= 0',
+ 'PositiveSmallIntegerField': '"%(column)s" >= 0',
+ }
data_types_suffix = {
'AutoField': 'AUTOINCREMENT',
'BigAutoField': 'AUTOINCREMENT',
diff --git a/django/db/backends/sqlite3/features.py b/django/db/backends/sqlite3/features.py
index 7563edf1c0..4d9f4985d4 100644
--- a/django/db/backends/sqlite3/features.py
+++ b/django/db/backends/sqlite3/features.py
@@ -14,7 +14,6 @@ class DatabaseFeatures(BaseDatabaseFeatures):
supports_timezones = False
max_query_params = 999
supports_mixed_date_datetime_comparisons = False
- supports_column_check_constraints = False
autocommits_when_autocommit_is_off = True
can_introspect_decimal_field = False
can_introspect_positive_integer_field = True
diff --git a/django/db/backends/sqlite3/introspection.py b/django/db/backends/sqlite3/introspection.py
index 75fb9a7ced..0c82ea8844 100644
--- a/django/db/backends/sqlite3/introspection.py
+++ b/django/db/backends/sqlite3/introspection.py
@@ -231,6 +231,32 @@ class DatabaseIntrospection(BaseDatabaseIntrospection):
one or more columns.
"""
constraints = {}
+ # Find inline check constraints.
+ try:
+ table_schema = cursor.execute(
+ "SELECT sql FROM sqlite_master WHERE type='table' and name=%s" % (
+ self.connection.ops.quote_name(table_name),
+ )
+ ).fetchone()[0]
+ except TypeError:
+ # table_name is a view.
+ pass
+ else:
+ fields_with_check_constraints = [
+ schema_row.strip().split(' ')[0][1:-1]
+ for schema_row in table_schema.split(',')
+ if schema_row.find('CHECK') >= 0
+ ]
+ for field_name in fields_with_check_constraints:
+ # An arbitrary made up name.
+ constraints['__check__%s' % field_name] = {
+ 'columns': [field_name],
+ 'primary_key': False,
+ 'unique': False,
+ 'foreign_key': False,
+ 'check': True,
+ 'index': False,
+ }
# Get the index info
cursor.execute("PRAGMA index_list(%s)" % self.connection.ops.quote_name(table_name))
for row in cursor.fetchall():
diff --git a/docs/releases/2.2.txt b/docs/releases/2.2.txt
index 8bcb3a113a..840d4b4d0d 100644
--- a/docs/releases/2.2.txt
+++ b/docs/releases/2.2.txt
@@ -218,7 +218,10 @@ Database backend API
Miscellaneous
-------------
-* ...
+* On SQLite, ``PositiveIntegerField`` and ``PositiveSmallIntegerField`` now
+ include a check constraint to prevent negative values in the database. If you
+ have existing invalid data and run a migration that recreates a table, you'll
+ see ``CHECK constraint failed``.
.. _deprecated-features-2.2: