1
0
mirror of https://github.com/django/django.git synced 2024-12-27 19:46:22 +00:00

[5.0.x] Fixed #34936 -- Fixed migration crash for DecimalField with db_default on SQLite.

CAST() must be wrapped in parentheses to be recognized as an expression on SQLite.

Regression in 7414704e88.

Backport of 797957fb48 from main
This commit is contained in:
David Sanders 2023-10-30 20:44:44 +11:00 committed by Mariusz Felisiak
parent b735b90f43
commit 8dde0504f3
4 changed files with 15 additions and 4 deletions

View File

@ -119,6 +119,10 @@ class DatabaseFeatures(BaseDatabaseFeatures):
"Oracle doesn't support comparing NCLOB to NUMBER.": { "Oracle doesn't support comparing NCLOB to NUMBER.": {
"generic_relations_regress.tests.GenericRelationTests.test_textlink_filter", "generic_relations_regress.tests.GenericRelationTests.test_textlink_filter",
}, },
"DecimalField.db_default doesn't return decimal.Decimal instances on Oracle "
"(#34941).": {
"field_defaults.tests.DefaultTests.test_field_db_defaults_returning",
},
} }
django_test_expected_failures = { django_test_expected_failures = {
# A bug in Django/oracledb with respect to string handling (#23843). # A bug in Django/oracledb with respect to string handling (#23843).

View File

@ -27,7 +27,7 @@ class SQLiteNumericMixin:
sql, params = self.as_sql(compiler, connection, **extra_context) sql, params = self.as_sql(compiler, connection, **extra_context)
try: try:
if self.output_field.get_internal_type() == "DecimalField": if self.output_field.get_internal_type() == "DecimalField":
sql = "CAST(%s AS NUMERIC)" % sql sql = "(CAST(%s AS NUMERIC))" % sql
except FieldError: except FieldError:
pass pass
return sql, params return sql, params

View File

@ -10,6 +10,7 @@ field.
""" """
from datetime import datetime from datetime import datetime
from decimal import Decimal
from django.db import models from django.db import models
from django.db.models.functions import Coalesce, ExtractYear, Now, Pi from django.db.models.functions import Coalesce, ExtractYear, Now, Pi
@ -33,6 +34,9 @@ class DBArticle(models.Model):
headline = models.CharField(max_length=100, db_default="Default headline") headline = models.CharField(max_length=100, db_default="Default headline")
pub_date = models.DateTimeField(db_default=Now()) pub_date = models.DateTimeField(db_default=Now())
cost = models.DecimalField(
max_digits=3, decimal_places=2, db_default=Decimal("3.33")
)
class Meta: class Meta:
required_db_features = {"supports_expression_defaults"} required_db_features = {"supports_expression_defaults"}

View File

@ -1,4 +1,5 @@
from datetime import datetime from datetime import datetime
from decimal import Decimal
from math import pi from math import pi
from django.db import connection from django.db import connection
@ -44,6 +45,7 @@ class DefaultTests(TestCase):
self.assertIsInstance(a.id, int) self.assertIsInstance(a.id, int)
self.assertEqual(a.headline, "Default headline") self.assertEqual(a.headline, "Default headline")
self.assertIsInstance(a.pub_date, datetime) self.assertIsInstance(a.pub_date, datetime)
self.assertEqual(a.cost, Decimal("3.33"))
@skipIfDBFeature("can_return_columns_from_insert") @skipIfDBFeature("can_return_columns_from_insert")
@skipUnlessDBFeature("supports_expression_defaults") @skipUnlessDBFeature("supports_expression_defaults")
@ -54,6 +56,7 @@ class DefaultTests(TestCase):
self.assertIsInstance(a.id, int) self.assertIsInstance(a.id, int)
self.assertEqual(a.headline, "Default headline") self.assertEqual(a.headline, "Default headline")
self.assertIsInstance(a.pub_date, datetime) self.assertIsInstance(a.pub_date, datetime)
self.assertEqual(a.cost, Decimal("3.33"))
def test_null_db_default(self): def test_null_db_default(self):
obj1 = DBDefaults.objects.create() obj1 = DBDefaults.objects.create()
@ -141,12 +144,12 @@ class DefaultTests(TestCase):
articles = [DBArticle(pub_date=pub_date), DBArticle(pub_date=pub_date)] articles = [DBArticle(pub_date=pub_date), DBArticle(pub_date=pub_date)]
DBArticle.objects.bulk_create(articles) DBArticle.objects.bulk_create(articles)
headlines = DBArticle.objects.values_list("headline", "pub_date") headlines = DBArticle.objects.values_list("headline", "pub_date", "cost")
self.assertSequenceEqual( self.assertSequenceEqual(
headlines, headlines,
[ [
("Default headline", pub_date), ("Default headline", pub_date, Decimal("3.33")),
("Default headline", pub_date), ("Default headline", pub_date, Decimal("3.33")),
], ],
) )