Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

First stab at MySQL support

  • Loading branch information...
commit cab044c66ca3d1f3cfc704f64364aced2b9645af 1 parent 60873ea
@andrewgodwin andrewgodwin authored
View
5 django/db/backends/mysql/base.py
@@ -37,6 +37,7 @@
from django.db.backends.mysql.creation import DatabaseCreation
from django.db.backends.mysql.introspection import DatabaseIntrospection
from django.db.backends.mysql.validation import DatabaseValidation
+from django.db.backends.mysql.schema import DatabaseSchemaEditor
from django.utils.functional import cached_property
from django.utils.safestring import SafeString, SafeUnicode
from django.utils import six
@@ -488,3 +489,7 @@ def check_constraints(self, table_names=None):
% (table_name, bad_row[0],
table_name, column_name, bad_row[1],
referenced_table_name, referenced_column_name))
+
+ def schema_editor(self):
+ "Returns a new instance of this backend's SchemaEditor"
+ return DatabaseSchemaEditor(self)
View
32 django/db/backends/mysql/introspection.py
@@ -102,3 +102,35 @@ def get_indexes(self, cursor, table_name):
indexes[row[4]] = {'primary_key': (row[2] == 'PRIMARY'), 'unique': not bool(row[1])}
return indexes
+ def get_constraints(self, cursor, table_name):
+ """
+ Retrieves any constraints (unique, pk, fk, check) across one or more columns.
+ Returns {'cnname': {'columns': set(columns), 'primary_key': bool, 'unique': bool}}
+ """
+ constraints = {}
+ # Loop over the constraint tables, collecting things as constraints
+ ifsc_tables = ["constraint_column_usage", "key_column_usage"]
+ for ifsc_table in ifsc_tables:
+ cursor.execute("""
+ SELECT kc.constraint_name, kc.column_name, c.constraint_type
+ FROM information_schema.%s AS kc
+ JOIN information_schema.table_constraints AS c ON
+ kc.table_schema = c.table_schema AND
+ kc.table_name = c.table_name AND
+ kc.constraint_name = c.constraint_name
+ WHERE
+ kc.table_schema = %%s AND
+ kc.table_name = %%s
+ """ % ifsc_table, [self.connection.settings_dict['NAME'], table_name])
+ for constraint, column, kind in cursor.fetchall():
+ # If we're the first column, make the record
+ if constraint not in constraints:
+ constraints[constraint] = {
+ "columns": set(),
+ "primary_key": kind.lower() == "primary key",
+ "foreign_key": kind.lower() == "foreign key",
+ "unique": kind.lower() in ["primary key", "unique"],
+ }
+ # Record the details
+ constraints[constraint]['columns'].add(column)
+ return constraints
View
24 django/db/backends/mysql/schema.py
@@ -0,0 +1,24 @@
+from django.db.backends.schema import BaseDatabaseSchemaEditor
+
+
+class DatabaseSchemaEditor(BaseDatabaseSchemaEditor):
+
+ sql_rename_table = "RENAME TABLE %(old_table)s TO %(new_table)s"
+
+ sql_alter_column_null = "MODIFY %(column)s %(type)s NULL"
+ sql_alter_column_not_null = "MODIFY %(column)s %(type)s NULL"
+
+ sql_delete_unique = "ALTER TABLE %(table)s DROP INDEX %(name)s"
+
+ sql_create_fk = "ALTER TABLE %(table)s ADD CONSTRAINT %(name)s FOREIGN KEY (%(column)s) REFERENCES %(to_table)s (%(to_column)s)"
+ sql_delete_fk = "ALTER TABLE %(table)s DROP FOREIGN KEY %(name)s"
+
+ sql_delete_index = "DROP INDEX %(name)s ON %(table_name)s"
+
+ sql_delete_pk = "ALTER TABLE %(table)s DROP PRIMARY KEY"
+
+
+
+
+ alter_string_set_null = 'MODIFY %(column)s %(type)s NULL;'
+ alter_string_drop_null = 'MODIFY %(column)s %(type)s NOT NULL;'
View
2  django/db/backends/postgresql_psycopg2/introspection.py
@@ -91,7 +91,7 @@ def get_indexes(self, cursor, table_name):
def get_constraints(self, cursor, table_name):
"""
- Retrieves any constraints (unique, pk, check) across one or more columns.
+ Retrieves any constraints (unique, pk, fk, check) across one or more columns.
Returns {'cnname': {'columns': set(columns), 'primary_key': bool, 'unique': bool}}
"""
constraints = {}
View
3  tests/modeltests/schema/tests.py
@@ -167,7 +167,6 @@ def test_alter(self):
# Ensure the field is right to begin with
columns = self.column_classes(Author)
self.assertEqual(columns['name'][0], "CharField")
- self.assertEqual(columns['name'][1][3], 255)
self.assertEqual(columns['name'][1][6], False)
# Alter the name field to a TextField
new_field = TextField(null=True)
@@ -197,7 +196,6 @@ def test_rename(self):
# Ensure the field is right to begin with
columns = self.column_classes(Author)
self.assertEqual(columns['name'][0], "CharField")
- self.assertEqual(columns['name'][1][3], 255)
self.assertNotIn("display_name", columns)
# Alter the name field's name
new_field = CharField(max_length=254)
@@ -213,7 +211,6 @@ def test_rename(self):
# Ensure the field is right afterwards
columns = self.column_classes(Author)
self.assertEqual(columns['display_name'][0], "CharField")
- self.assertEqual(columns['display_name'][1][3], 254)
self.assertNotIn("name", columns)
def test_m2m(self):
Please sign in to comment.
Something went wrong with that request. Please try again.