Skip to content

Instantly share code, notes, and snippets.

@Buzovskiy
Last active August 4, 2021 07:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Buzovskiy/d666fb798a12946a9bbebebdfb79bce1 to your computer and use it in GitHub Desktop.
Save Buzovskiy/d666fb798a12946a9bbebebdfb79bce1 to your computer and use it in GitHub Desktop.
Django script for changing the settings of field with foreign key. Foreign key changes in several steps: 1) Retrieve foreign keys from database; 2) Delete foreign keys; 3) Change fields; 4) Add foreign keys.
from django.db import connection
from pprint import pprint, pformat
# Database name
referenced_table_schema = connection.settings_dict['NAME']
# Table being referenced by foreign keys of another tables
referenced_table_name = "lang"
# Field being referenced by another tables
referenced_column_name = "id_lang"
with connection.cursor() as cursor:
# 1. Get tables and fields, whose FK reference field referenced_column_name of the table referenced_table_name
cursor.execute(
"""
SELECT
TABLE_NAME
,COLUMN_NAME
,CONSTRAINT_NAME
,REFERENCED_TABLE_NAME
,REFERENCED_COLUMN_NAME
FROM
INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE
REFERENCED_TABLE_SCHEMA = %s AND
REFERENCED_TABLE_NAME = %s AND
REFERENCED_COLUMN_NAME = %s
""", [referenced_table_schema, referenced_table_name, referenced_column_name])
columns = [col[0] for col in cursor.description]
result = [dict(zip(columns, row)) for row in cursor.fetchall()]
for foreignkey in result:
# 2. Remove FK of the tables, which reference the field referenced_column_name of table referenced_table_name
cursor.execute(
"""
ALTER TABLE {db}.{table} DROP FOREIGN KEY {fk}
""".format(db=referenced_table_schema, table=foreignkey['TABLE_NAME'], fk=foreignkey['CONSTRAINT_NAME'])
)
# 3. Once the FK is removed the function of field changing is available
cursor.execute(
"""
ALTER TABLE {db}.{table} CHANGE {column} {column} INT(11) NOT NULL;
""".format(db=referenced_table_schema, table=foreignkey['TABLE_NAME'], column=foreignkey['COLUMN_NAME'])
)
# 4. Change field, that foreign keys are referenced
cursor.execute(
"""
ALTER TABLE {db}.{table} CHANGE {column} {column} INT(11) NOT NULL AUTO_INCREMENT;
""".format(db=referenced_table_schema, table=referenced_table_name, column=referenced_column_name)
)
# 5. Create FK for tables
for foreignkey in result:
cursor.execute(
"""
ALTER TABLE {db}.{table} ADD FOREIGN KEY ({column})
REFERENCES {referenced_table}({referenced_column}) ON DELETE CASCADE ON UPDATE CASCADE;
""".format(
db=referenced_table_schema,
table=foreignkey['TABLE_NAME'],
column=foreignkey['COLUMN_NAME'],
referenced_table=referenced_table_name,
referenced_column=referenced_column_name
)
)
print('finish')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment