mirror of
https://github.com/django/django.git
synced 2025-08-03 10:34:04 +00:00
Fixed #30183 -- Added introspection of inline SQLite constraints.
This commit is contained in:
parent
406de977ea
commit
782d85b6df
5 changed files with 332 additions and 51 deletions
|
@ -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'),
|
||||
]
|
||||
|
|
|
@ -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())
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue