summaryrefslogtreecommitdiff
path: root/tests/introspection
diff options
context:
space:
mode:
authorPaveł Tyślacki <pavel.tyslacki@gmail.com>2019-02-28 00:47:29 +0300
committerTim Graham <timograham@gmail.com>2019-03-13 10:24:28 -0400
commit782d85b6dfa191e67c0f1d572641d8236c79174c (patch)
tree8ca589140652b19f60941c5ff2d361ed81d491d7 /tests/introspection
parent406de977ea1a6429535d21240e3ecdac06d4516c (diff)
downloaddjango-782d85b6dfa191e67c0f1d572641d8236c79174c.tar.gz
Fixed #30183 -- Added introspection of inline SQLite constraints.
Diffstat (limited to 'tests/introspection')
-rw-r--r--tests/introspection/models.py18
-rw-r--r--tests/introspection/tests.py59
2 files changed, 76 insertions, 1 deletions
diff --git a/tests/introspection/models.py b/tests/introspection/models.py
index 32acc323bd..fa663de2fd 100644
--- a/tests/introspection/models.py
+++ b/tests/introspection/models.py
@@ -58,3 +58,21 @@ class ArticleReporter(models.Model):
class Meta:
managed = False
+
+
+class Comment(models.Model):
+ ref = models.UUIDField(unique=True)
+ article = models.ForeignKey(Article, models.CASCADE, db_index=True)
+ email = models.EmailField()
+ pub_date = models.DateTimeField()
+ up_votes = models.PositiveIntegerField()
+ body = models.TextField()
+
+ class Meta:
+ constraints = [
+ models.CheckConstraint(name='up_votes_gte_0_check', check=models.Q(up_votes__gte=0)),
+ models.UniqueConstraint(fields=['article', 'email', 'pub_date'], name='article_email_pub_date_uniq'),
+ ]
+ indexes = [
+ models.Index(fields=['email', 'pub_date'], name='email_pub_date_idx'),
+ ]
diff --git a/tests/introspection/tests.py b/tests/introspection/tests.py
index d851352cae..10524cdacb 100644
--- a/tests/introspection/tests.py
+++ b/tests/introspection/tests.py
@@ -5,7 +5,7 @@ from django.db.models import Index
from django.db.utils import DatabaseError
from django.test import TransactionTestCase, skipUnlessDBFeature
-from .models import Article, ArticleReporter, City, District, Reporter
+from .models import Article, ArticleReporter, City, Comment, District, Reporter
class IntrospectionTests(TransactionTestCase):
@@ -211,3 +211,60 @@ class IntrospectionTests(TransactionTestCase):
self.assertEqual(val['orders'], ['ASC'] * len(val['columns']))
indexes_verified += 1
self.assertEqual(indexes_verified, 4)
+
+ def test_get_constraints(self):
+ def assertDetails(details, cols, primary_key=False, unique=False, index=False, check=False, foreign_key=None):
+ # Different backends have different values for same constraints:
+ # PRIMARY KEY UNIQUE CONSTRAINT UNIQUE INDEX
+ # MySQL pk=1 uniq=1 idx=1 pk=0 uniq=1 idx=1 pk=0 uniq=1 idx=1
+ # PostgreSQL pk=1 uniq=1 idx=0 pk=0 uniq=1 idx=0 pk=0 uniq=1 idx=1
+ # SQLite pk=1 uniq=0 idx=0 pk=0 uniq=1 idx=0 pk=0 uniq=1 idx=1
+ if details['primary_key']:
+ details['unique'] = True
+ if details['unique']:
+ details['index'] = False
+ self.assertEqual(details['columns'], cols)
+ self.assertEqual(details['primary_key'], primary_key)
+ self.assertEqual(details['unique'], unique)
+ self.assertEqual(details['index'], index)
+ self.assertEqual(details['check'], check)
+ self.assertEqual(details['foreign_key'], foreign_key)
+
+ with connection.cursor() as cursor:
+ constraints = connection.introspection.get_constraints(cursor, Comment._meta.db_table)
+ # Test custom constraints
+ custom_constraints = {
+ 'article_email_pub_date_uniq',
+ 'email_pub_date_idx',
+ }
+ if connection.features.supports_column_check_constraints:
+ custom_constraints.add('up_votes_gte_0_check')
+ assertDetails(constraints['up_votes_gte_0_check'], ['up_votes'], check=True)
+ assertDetails(constraints['article_email_pub_date_uniq'], ['article_id', 'email', 'pub_date'], unique=True)
+ assertDetails(constraints['email_pub_date_idx'], ['email', 'pub_date'], index=True)
+ # Test field constraints
+ field_constraints = set()
+ for name, details in constraints.items():
+ if name in custom_constraints:
+ continue
+ elif details['columns'] == ['up_votes'] and details['check']:
+ assertDetails(details, ['up_votes'], check=True)
+ field_constraints.add(name)
+ elif details['columns'] == ['ref'] and details['unique']:
+ assertDetails(details, ['ref'], unique=True)
+ field_constraints.add(name)
+ elif details['columns'] == ['article_id'] and details['index']:
+ assertDetails(details, ['article_id'], index=True)
+ field_constraints.add(name)
+ elif details['columns'] == ['id'] and details['primary_key']:
+ assertDetails(details, ['id'], primary_key=True, unique=True)
+ field_constraints.add(name)
+ elif details['columns'] == ['article_id'] and details['foreign_key']:
+ assertDetails(details, ['article_id'], foreign_key=('introspection_article', 'id'))
+ field_constraints.add(name)
+ elif details['check']:
+ # Some databases (e.g. Oracle) include additional check
+ # constraints.
+ field_constraints.add(name)
+ # All constraints are accounted for.
+ self.assertEqual(constraints.keys() ^ (custom_constraints | field_constraints), set())