Skip to content

Commit

Permalink
Implement param escaping for migraionts
Browse files Browse the repository at this point in the history
  • Loading branch information
codingjoe committed Jan 31, 2020
1 parent 98cdd0c commit 6bef39c
Show file tree
Hide file tree
Showing 3 changed files with 13 additions and 17 deletions.
12 changes: 10 additions & 2 deletions django/db/backends/base/schema.py
Expand Up @@ -223,7 +223,11 @@ def column_sql(self, model, field, include_default=False):
default_value = self.effective_default(field)
column_default = ' DEFAULT ' + self._column_default_sql(field)
if default_value is not None:
if self.connection.features.requires_literal_defaults:
if hasattr(default_value, 'as_sql'):
s, p = default_value.as_sql(self, self.connection)
sql += column_default % s
params += p
elif self.connection.features.requires_literal_defaults:
# Some databases can't take defaults as a parameter (oracle)
# If this is the case, the individual schema backend should
# implement prepare_default
Expand Down Expand Up @@ -480,7 +484,11 @@ def add_field(self, model, field):
"column": self.quote_name(field.column),
"definition": definition,
}
self.execute(sql, params)
try:
self.execute(sql, params)
except:
print(sql, params)
raise
# Drop the default if we need to
# (Django usually does not use in-database defaults)
if not self.skip_default(field) and self.effective_default(field) is not None:
Expand Down
6 changes: 1 addition & 5 deletions tests/schema/models.py
Expand Up @@ -9,16 +9,12 @@
new_apps = Apps()


class DBRetruningDateTimeField(models.DateTimeField):
db_returning = True


class Author(models.Model):
name = models.CharField(max_length=255)
height = models.PositiveIntegerField(null=True, blank=True)
weight = models.IntegerField(null=True, blank=True)
uuid = models.UUIDField(null=True)
date_of_birth = DBRetruningDateTimeField(default=Now)
date_of_birth = models.DateTimeField(default=Now)

class Meta:
apps = new_apps
Expand Down
12 changes: 2 additions & 10 deletions tests/schema/tests.py
Expand Up @@ -2649,15 +2649,12 @@ def test_add_field_use_effective_default(self):
self.assertEqual(item[0], None if connection.features.interprets_empty_strings_as_nulls else '')

def test_add_field_default_db_returning(self):
class CreatedDateTimeField(DateTimeField):
db_returning = True

# Create the table.
with connection.schema_editor() as editor:
editor.create_model(Author)
# Add new field with database default.
Author.objects.create(name='author 1')
new_field = CreatedDateTimeField(default=Now)
new_field = DateTimeField(default=Now)
new_field.set_attributes_from_name('db_returning')
with connection.schema_editor() as editor:
editor.add_field(Author, new_field)
Expand All @@ -2668,21 +2665,16 @@ class CreatedDateTimeField(DateTimeField):
self.assertIsNotNone(item[0])

def test_alter_field_default_db_returning(self):
class PubDateTimeField(DateTimeField):
db_returning = True

# Create the table.
with connection.schema_editor() as editor:
editor.create_model(BookWithoutAuthor)
BookWithoutAuthor.objects.create(title='book 1', pub_date=datetime.datetime.now())
# Alter to add field with database default.
old_field = BookWithoutAuthor._meta.get_field('pub_date')
new_field = PubDateTimeField(default=Now)
new_field = DateTimeField(default=Now)
new_field.set_attributes_from_name('pub_date')
with connection.schema_editor() as editor:
editor.alter_field(BookWithoutAuthor, old_field, new_field, strict=True)
book = BookWithoutAuthor.objects.create(title='book 2')
self.assertIsInstance(book.pub_date, datetime.datetime)

def test_effective_default_db_default(self):
"""#31206 - effective_default() should be handle database defaults"""
Expand Down

0 comments on commit 6bef39c

Please sign in to comment.