Commit e60cce4e authored by Adam Chainz's avatar Adam Chainz Committed by Tim Graham
Browse files

Fixed #24846 -- Added support to MySQL SchemaEditor for all blob/text data types

parent 00e8e514
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -8,6 +8,7 @@ answer newbie questions, and generally made Django that much better:
    Aaron Cannon <cannona@fireantproductions.com>
    Aaron Swartz <http://www.aaronsw.com/>
    Aaron T. Myers <atmyers@gmail.com>
    Adam Johnson <https://github.com/adamchainz>
    Adam Vandenberg
    Adrian Holovaty <adrian@holovaty.com>
    Adrien Lemaire <lemaire.adrien@gmail.com>
+10 −3
Original line number Diff line number Diff line
@@ -34,10 +34,17 @@ class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):

    def skip_default(self, field):
        """
        MySQL doesn't accept default values for longtext and longblob
        and implicitly treats these columns as nullable.
        MySQL doesn't accept default values for TEXT and BLOB types, and
        implicitly treats these columns as nullable.
        """
        return field.db_type(self.connection) in {'longtext', 'longblob'}
        db_type = field.db_type(self.connection)
        return (
            db_type is not None and
            db_type.lower() in {
                'tinyblob', 'blob', 'mediumblob', 'longblob',
                'tinytext', 'text', 'mediumtext', 'longtext',
            }
        )

    def add_field(self, model, field):
        super(DatabaseSchemaEditor, self).add_field(model, field)
+9 −0
Original line number Diff line number Diff line
from django.db import models
from django.db.models.fields.related import (
    RECURSIVE_RELATIONSHIP_CONSTANT, ManyRelatedObjectsDescriptor,
    ManyToManyField, ManyToManyRel, RelatedField,
@@ -56,3 +57,11 @@ class CustomManyToManyField(RelatedField):

class InheritedManyToManyField(ManyToManyField):
    pass


class MediumBlobField(models.BinaryField):
    """
    A MySQL BinaryField that uses a different blob size.
    """
    def db_type(self, connection):
        return 'MEDIUMBLOB'
+20 −1
Original line number Diff line number Diff line
@@ -17,7 +17,9 @@ from django.db.models.fields.related import (
from django.db.transaction import atomic
from django.test import TransactionTestCase, skipIfDBFeature

from .fields import CustomManyToManyField, InheritedManyToManyField
from .fields import (
    CustomManyToManyField, InheritedManyToManyField, MediumBlobField,
)
from .models import (
    Author, AuthorWithDefaultHeight, AuthorWithEvenLongerName, Book, BookWeak,
    BookWithLongName, BookWithO2O, BookWithSlug, Note, NoteRename, Tag,
@@ -383,6 +385,23 @@ class SchemaTests(TransactionTestCase):
        # these two types.
        self.assertIn(columns['bits'][0], ("BinaryField", "TextField"))

    @unittest.skipUnless(connection.vendor == 'mysql', "MySQL specific")
    def test_add_binaryfield_mediumblob(self):
        """
        Test adding a custom-sized binary field on MySQL (#24846).
        """
        # Create the table
        with connection.schema_editor() as editor:
            editor.create_model(Author)
        # Add the new field with default
        new_field = MediumBlobField(blank=True, default=b'123')
        new_field.set_attributes_from_name('bits')
        with connection.schema_editor() as editor:
            editor.add_field(Author, new_field)
        columns = self.column_classes(Author)
        # Introspection treats BLOBs as TextFields
        self.assertEqual(columns['bits'][0], "TextField")

    def test_alter(self):
        """
        Tests simple altering of fields