Forked from benjaoming/migratemigrations2django2.py
Created
February 27, 2021 09:30
-
-
Save wsantos/d0d8b6438e5d0c0d6be171fae5c807e0 to your computer and use it in GitHub Desktop.
Adds required keyword on_delete to ForeignKey and OneToOneField in Django migrations
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python3 | |
""" | |
This script adds on_delete to Django migrations. It works on multi-line | |
definitions of ForeignKey/OneToOneField which may be in your codebase if you | |
have black'ened the migration files. | |
It's not perfect, but it doesn't create syntax errors and you can run black on | |
the code again afterwards. | |
First version: | |
https://gist.github.com/benjaoming/3e5770ffcf029c1e11d9a7f79f2e7f89 | |
https://stackoverflow.com/questions/41571281/easy-way-to-set-on-delete-across-entire-application | |
https://stackoverflow.com/questions/11898998/how-can-i-write-a-regex-which-matches-non-greedy | |
https://stackoverflow.com/questions/15474741/python-regex-optional-capture-group | |
""" | |
import re | |
from pathlib import Path | |
regex = re.compile( | |
r"(ForeignKey|OneToOneField)\((\n?\s*([^\)]|\"[^\"]+\")+)(:?[\,\s\n]*)?\)(\,?\n)", | |
re.MULTILINE, | |
) | |
index = 0 | |
for filename in Path(".").glob("**/migrations/*.py"): | |
print(filename) | |
contents = open(filename, "r").read() | |
matches = re.finditer(regex, contents) | |
for a in matches: | |
# on_delete is already part of the expression | |
if "on_delete" in a.group(0): | |
continue | |
max_indents = 0 | |
for line in a.group(0).split("\n"): | |
indents = len(line) - len(line.strip()) | |
max_indents = max(max_indents, indents) | |
# A in-line expression of kwargs | |
if len(a.group(0).split("\n")) < 5: | |
contents = contents.replace( | |
a.group(0), | |
"{}({}, on_delete=models.CASCADE\n{}),\n{}".format( | |
a.group(1), | |
a.group(2).rstrip(), | |
" " * (max_indents - 4), | |
a.group(3) or "", | |
), | |
) | |
continue | |
contents = contents.replace( | |
a.group(0), | |
"{}({} on_delete=models.CASCADE,\n{}),{}\n".format( | |
a.group(1), a.group(2), " " * (max_indents - 4), a.group(3) or "" | |
), | |
) | |
# This is the match, print it to verify | |
# print(a.group(0)) | |
open(filename, "w").write(contents) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment