- Author:
- m_tayseer
- Posted:
- November 18, 2008
- Language:
- Python
- Version:
- 1.0
- Score:
- 0 (after 0 ratings)
python manage.py inspectdb
allows you to generate the models from a legacy database. The generated model classes are not arranged by dependencies. When the number of tables is big, it becomes really painful to rearrange by hand.
This small script should rearrange the models for you. It doesn't solve every problem with generated models, but it makes our the process easier
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | ''' Usage
python rearrange_models.py inspected_models.py ordered_models.py
'''
import re
from cStringIO import StringIO
class DjangoModelsArrangement:
def __init__(self):
self.output = StringIO()
self.classes = {}
self.already_written = set()
def get_classes(self, input):
# This regular expression will divide the input as
# [file_header, class_declaration1, class_body1, class_declaration2, class_body2, ...]
parsed_classes = re.split(r'(class\s+.*?\(models\.Model\):)', input)
self.header = parsed_classes[0]
return [i+j for i, j in zip(parsed_classes[1::2], parsed_classes[2::2])]
def parse_class(self, class_def):
lines = class_def.split('\n')
class_decl, class_body = lines[0], lines[1:]
class_name = re.findall(r'class\s+(.*?)\(models\.Model\):', class_decl)[0]
referenced_set = set()
for line in lines:
if 'ForeignKey' in line:
referenced_class = re.findall(r'ForeignKey\((.*?)(?:,|\))', line)[0]
if referenced_class and referenced_class != "'self'":
referenced_set.add(referenced_class)
self.classes[class_name] = (referenced_set, class_def)
def write_class(self, class_):
if class_ not in self.already_written:
self.already_written.add(class_)
referenced_set, class_def = self.classes[class_]
if referenced_set:
for referenced_class in referenced_set:
self.write_class(referenced_class)
self.output.write(class_def)
def arrange(self, source_file, dest_file):
input = open(source_file).read()
classes = self.get_classes(input)
for class_ in classes:
self.parse_class(class_)
for class_ in self.classes:
self.write_class(class_)
output_data = self.output.getvalue()
open(dest_file, 'w').write(self.header + output_data)
if __name__ == '__main__':
import sys
if len(sys.argv) != 3:
print __doc__
sys.exit(1)
DjangoModelsArrangement().arrange(sys.argv[1], sys.argv[2])
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
- Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
- Help text hyperlinks by sa2812 1 year, 8 months ago
Comments
I fixed a bug where this script would raise a 'RuntimeError: maximum recursion depth exceeded'
#
Please login first before commenting.