| author | ymh <ymh.work@gmail.com> |
| Wed, 20 Jan 2010 12:37:40 +0100 | |
| changeset 3 | 526ebd3988b0 |
| permissions | -rw-r--r-- |
|
3
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
1 |
""" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
2 |
sqldiff.py - Prints the (approximated) difference between models and database |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
3 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
4 |
TODO: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
5 |
- better support for relations |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
6 |
- better support for constraints (mainly postgresql?) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
7 |
- support for table spaces with postgresql |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
8 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
9 |
KNOWN ISSUES: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
10 |
- MySQL has by far the most problems with introspection. Please be |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
11 |
carefull when using MySQL with sqldiff. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
12 |
- Booleans are reported back as Integers, so there's know way to know if |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
13 |
there was a real change. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
14 |
- Varchar sizes are reported back without unicode support so there size |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
15 |
may change in comparison to the real length of the varchar. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
16 |
- Some of the 'fixes' to counter these problems might create false |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
17 |
positives or false negatives. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
18 |
""" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
19 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
20 |
from django.core.management.base import BaseCommand |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
21 |
from django.core.management import sql as _sql |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
22 |
from django.core.management import CommandError |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
23 |
from django.core.management.color import no_style |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
24 |
from django.db import transaction, connection |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
25 |
from django.db.models.fields import IntegerField |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
26 |
from optparse import make_option |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
27 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
28 |
ORDERING_FIELD = IntegerField('_order', null=True) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
29 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
30 |
def flatten(l, ltypes=(list, tuple)): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
31 |
ltype = type(l) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
32 |
l = list(l) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
33 |
i = 0 |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
34 |
while i < len(l): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
35 |
while isinstance(l[i], ltypes): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
36 |
if not l[i]: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
37 |
l.pop(i) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
38 |
i -= 1 |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
39 |
break |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
40 |
else: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
41 |
l[i:i + 1] = l[i] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
42 |
i += 1 |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
43 |
return ltype(l) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
44 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
45 |
class SQLDiff(object): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
46 |
DATA_TYPES_REVERSE_OVERRIDE = { |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
47 |
} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
48 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
49 |
DIFF_TYPES = [ |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
50 |
'comment', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
51 |
'table-missing-in-db', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
52 |
'field-missing-in-db', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
53 |
'field-missing-in-model', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
54 |
'index-missing-in-db', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
55 |
'index-missing-in-model', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
56 |
'unique-missing-in-db', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
57 |
'unique-missing-in-model', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
58 |
'field-type-differ', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
59 |
'field-parameter-differ', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
60 |
] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
61 |
DIFF_TEXTS = { |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
62 |
'comment': 'comment: %(0)s', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
63 |
'table-missing-in-db': "table '%(0)s' missing in database", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
64 |
'field-missing-in-db' : "field '%(1)s' defined in model but missing in database", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
65 |
'field-missing-in-model' : "field '%(1)s' defined in database but missing in model", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
66 |
'index-missing-in-db' : "field '%(1)s' INDEX defined in model but missing in database", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
67 |
'index-missing-in-model' : "field '%(1)s' INDEX defined in database schema but missing in model", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
68 |
'unique-missing-in-db' : "field '%(1)s' UNIQUE defined in model but missing in database", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
69 |
'unique-missing-in-model' : "field '%(1)s' UNIQUE defined in database schema but missing in model", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
70 |
'field-type-differ' : "field '%(1)s' not of same type: db='%(3)s', model='%(2)s'", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
71 |
'field-parameter-differ' : "field '%(1)s' parameters differ: db='%(3)s', model='%(2)s'", |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
72 |
} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
73 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
74 |
SQL_FIELD_MISSING_IN_DB = lambda self, style, qn, args: "%s %s\n\t%s %s %s;" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD('ADD'), style.SQL_FIELD(qn(args[1])), style.SQL_COLTYPE(args[2])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
75 |
SQL_FIELD_MISSING_IN_MODEL = lambda self, style, qn, args: "%s %s\n\t%s %s;" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD('DROP COLUMN'), style.SQL_FIELD(qn(args[1]))) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
76 |
SQL_INDEX_MISSING_IN_DB = lambda self, style, qn, args: "%s %s\n\t%s %s (%s);" % (style.SQL_KEYWORD('CREATE INDEX'), style.SQL_TABLE(qn("%s_idx" % '_'.join(args[0:2]))), style.SQL_KEYWORD('ON'), style.SQL_TABLE(qn(args[0])), style.SQL_FIELD(qn(args[1]))) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
77 |
# FIXME: need to lookup index name instead of just appending _idx to table + fieldname |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
78 |
SQL_INDEX_MISSING_IN_MODEL = lambda self, style, qn, args: "%s %s;" % (style.SQL_KEYWORD('DROP INDEX'), style.SQL_TABLE(qn("%s_idx" % '_'.join(args[0:2])))) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
79 |
SQL_UNIQUE_MISSING_IN_DB = lambda self, style, qn, args: "%s %s\n\t%s %s (%s);" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD('ADD'), style.SQL_KEYWORD('UNIQUE'), style.SQL_FIELD(qn(args[1]))) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
80 |
# FIXME: need to lookup unique constraint name instead of appending _key to table + fieldname |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
81 |
SQL_UNIQUE_MISSING_IN_MODEL = lambda self, style, qn, args: "%s %s\n\t%s %s %s;" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD('DROP'), style.SQL_KEYWORD('CONSTRAINT'), style.SQL_TABLE(qn("%s_key" % ('_'.join(args[:2]))))) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
82 |
SQL_FIELD_TYPE_DIFFER = lambda self, style, qn, args: "%s %s\n\t%s %s %s;" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD("MODIFY"), style.SQL_FIELD(qn(args[1])), style.SQL_COLTYPE(args[2])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
83 |
SQL_FIELD_PARAMETER_DIFFER = lambda self, style, qn, args: "%s %s\n\t%s %s %s;" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD("MODIFY"), style.SQL_FIELD(qn(args[1])), style.SQL_COLTYPE(args[2])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
84 |
SQL_COMMENT = lambda self, style, qn, args: style.NOTICE('-- Comment: %s' % style.SQL_TABLE(args[0])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
85 |
SQL_TABLE_MISSING_IN_DB = lambda self, style, qn, args: style.NOTICE('-- Table missing: %s' % args[0]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
86 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
87 |
def __init__(self, app_models, options): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
88 |
self.app_models = app_models |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
89 |
self.options = options |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
90 |
self.dense = options.get('dense_output', False) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
91 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
92 |
try: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
93 |
self.introspection = connection.introspection |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
94 |
except AttributeError: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
95 |
from django.db import get_introspection_module |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
96 |
self.introspection = get_introspection_module() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
97 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
98 |
self.cursor = connection.cursor() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
99 |
self.django_tables = self.get_django_tables(options.get('only_existing', True)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
100 |
self.db_tables = self.introspection.get_table_list(self.cursor) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
101 |
self.differences = [] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
102 |
self.unknown_db_fields = {} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
103 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
104 |
self.DIFF_SQL = { |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
105 |
'comment': self.SQL_COMMENT, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
106 |
'table-missing-in-db': self.SQL_TABLE_MISSING_IN_DB, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
107 |
'field-missing-in-db': self.SQL_FIELD_MISSING_IN_DB, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
108 |
'field-missing-in-model': self.SQL_FIELD_MISSING_IN_MODEL, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
109 |
'index-missing-in-db': self.SQL_INDEX_MISSING_IN_DB, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
110 |
'index-missing-in-model': self.SQL_INDEX_MISSING_IN_MODEL, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
111 |
'unique-missing-in-db': self.SQL_UNIQUE_MISSING_IN_DB, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
112 |
'unique-missing-in-model': self.SQL_UNIQUE_MISSING_IN_MODEL, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
113 |
'field-type-differ': self.SQL_FIELD_TYPE_DIFFER, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
114 |
'field-parameter-differ': self.SQL_FIELD_PARAMETER_DIFFER, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
115 |
} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
116 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
117 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
118 |
def add_app_model_marker(self, app_label, model_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
119 |
self.differences.append((app_label, model_name, [])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
120 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
121 |
def add_difference(self, diff_type, *args): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
122 |
assert diff_type in self.DIFF_TYPES, 'Unknown difference type' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
123 |
self.differences[-1][-1].append((diff_type, args)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
124 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
125 |
def get_django_tables(self, only_existing): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
126 |
try: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
127 |
django_tables = self.introspection.django_table_names(only_existing=only_existing) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
128 |
except AttributeError: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
129 |
# backwards compatibility for before introspection refactoring (r8296) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
130 |
try: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
131 |
django_tables = _sql.django_table_names(only_existing=only_existing) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
132 |
except AttributeError: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
133 |
# backwards compatibility for before svn r7568 |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
134 |
django_tables = _sql.django_table_list(only_existing=only_existing) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
135 |
return django_tables |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
136 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
137 |
def sql_to_dict(self, query,param): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
138 |
""" sql_to_dict(query, param) -> list of dicts |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
139 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
140 |
code from snippet at http://www.djangosnippets.org/snippets/1383/ |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
141 |
""" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
142 |
cursor = connection.cursor() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
143 |
cursor.execute(query,param) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
144 |
fieldnames = [name[0] for name in cursor.description] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
145 |
result = [] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
146 |
for row in cursor.fetchall(): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
147 |
rowset = [] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
148 |
for field in zip(fieldnames, row): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
149 |
rowset.append(field) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
150 |
result.append(dict(rowset)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
151 |
return result |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
152 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
153 |
def get_field_model_type(self, field): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
154 |
return field.db_type() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
155 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
156 |
def get_field_db_type(self, description, field=None, table_name=None): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
157 |
from django.db import models |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
158 |
# DB-API cursor.description |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
159 |
#(name, type_code, display_size, internal_size, precision, scale, null_ok) = description |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
160 |
type_code = description[1] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
161 |
if type_code in self.DATA_TYPES_REVERSE_OVERRIDE: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
162 |
reverse_type = self.DATA_TYPES_REVERSE_OVERRIDE[type_code] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
163 |
else: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
164 |
try: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
165 |
try: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
166 |
reverse_type = self.introspection.data_types_reverse[type_code] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
167 |
except AttributeError: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
168 |
# backwards compatibility for before introspection refactoring (r8296) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
169 |
reverse_type = self.introspection.DATA_TYPES_REVERSE.get(type_code) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
170 |
except KeyError: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
171 |
# type_code not found in data_types_reverse map |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
172 |
key = (self.differences[-1][:2], description[:2]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
173 |
if key not in self.unknown_db_fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
174 |
self.unknown_db_fields[key] = 1 |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
175 |
self.add_difference('comment', "Unknown database type for field '%s' (%s)" % (description[0], type_code)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
176 |
return None |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
177 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
178 |
kwargs = {} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
179 |
if isinstance(reverse_type, tuple): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
180 |
kwargs.update(reverse_type[1]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
181 |
reverse_type = reverse_type[0] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
182 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
183 |
if reverse_type == "CharField" and description[3]: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
184 |
kwargs['max_length'] = description[3] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
185 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
186 |
if reverse_type == "DecimalField": |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
187 |
kwargs['max_digits'] = description[4] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
188 |
kwargs['decimal_places'] = description[5] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
189 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
190 |
if description[6]: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
191 |
kwargs['blank'] = True |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
192 |
if not reverse_type in ('TextField', 'CharField'): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
193 |
kwargs['null'] = True |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
194 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
195 |
field_db_type = getattr(models, reverse_type)(**kwargs).db_type() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
196 |
return field_db_type |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
197 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
198 |
def strip_parameters(self, field_type): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
199 |
if field_type: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
200 |
return field_type.split(" ")[0].split("(")[0] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
201 |
return field_type |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
202 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
203 |
def find_unique_missing_in_db(self, meta, table_indexes, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
204 |
for field in meta.fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
205 |
if field.unique: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
206 |
attname = field.db_column or field.attname |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
207 |
if attname in table_indexes and table_indexes[attname]['unique']: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
208 |
continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
209 |
self.add_difference('unique-missing-in-db', table_name, attname) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
210 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
211 |
def find_unique_missing_in_model(self, meta, table_indexes, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
212 |
# TODO: Postgresql does not list unique_togethers in table_indexes |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
213 |
# MySQL does |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
214 |
fields = dict([(field.db_column or field.name, field.unique) for field in meta.fields]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
215 |
for att_name, att_opts in table_indexes.iteritems(): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
216 |
if att_opts['unique'] and att_name in fields and not fields[att_name]: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
217 |
if att_name in flatten(meta.unique_together): continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
218 |
self.add_difference('unique-missing-in-model', table_name, att_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
219 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
220 |
def find_index_missing_in_db(self, meta, table_indexes, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
221 |
for field in meta.fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
222 |
if field.db_index: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
223 |
attname = field.db_column or field.attname |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
224 |
if not attname in table_indexes: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
225 |
self.add_difference('index-missing-in-db', table_name, attname) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
226 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
227 |
def find_index_missing_in_model(self, meta, table_indexes, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
228 |
fields = dict([(field.name, field) for field in meta.fields]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
229 |
for att_name, att_opts in table_indexes.iteritems(): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
230 |
if att_name in fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
231 |
field = fields[att_name] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
232 |
if field.db_index: continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
233 |
if att_opts['primary_key'] and field.primary_key: continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
234 |
if att_opts['unique'] and field.unique: continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
235 |
if att_opts['unique'] and att_name in flatten(meta.unique_together): continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
236 |
self.add_difference('index-missing-in-model', table_name, att_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
237 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
238 |
def find_field_missing_in_model(self, fieldmap, table_description, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
239 |
for row in table_description: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
240 |
if row[0] not in fieldmap: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
241 |
self.add_difference('field-missing-in-model', table_name, row[0]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
242 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
243 |
def find_field_missing_in_db(self, fieldmap, table_description, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
244 |
db_fields = [row[0] for row in table_description] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
245 |
for field_name, field in fieldmap.iteritems(): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
246 |
if field_name not in db_fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
247 |
self.add_difference('field-missing-in-db', table_name, field_name, field.db_type()) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
248 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
249 |
def find_field_type_differ(self, meta, table_description, table_name, func=None): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
250 |
db_fields = dict([(row[0], row) for row in table_description]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
251 |
for field in meta.fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
252 |
if field.name not in db_fields: continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
253 |
description = db_fields[field.name] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
254 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
255 |
model_type = self.strip_parameters(self.get_field_model_type(field)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
256 |
db_type = self.strip_parameters(self.get_field_db_type(description, field)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
257 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
258 |
# use callback function if defined |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
259 |
if func: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
260 |
model_type, db_type = func(field, description, model_type, db_type) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
261 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
262 |
if not model_type==db_type: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
263 |
self.add_difference('field-type-differ', table_name, field.name, model_type, db_type) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
264 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
265 |
def find_field_parameter_differ(self, meta, table_description, table_name, func=None): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
266 |
db_fields = dict([(row[0], row) for row in table_description]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
267 |
for field in meta.fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
268 |
if field.name not in db_fields: continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
269 |
description = db_fields[field.name] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
270 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
271 |
model_type = self.get_field_model_type(field) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
272 |
db_type = self.get_field_db_type(description, field, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
273 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
274 |
if not self.strip_parameters(model_type)==self.strip_parameters(db_type): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
275 |
continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
276 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
277 |
# use callback function if defined |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
278 |
if func: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
279 |
model_type, db_type = func(field, description, model_type, db_type) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
280 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
281 |
if not model_type==db_type: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
282 |
self.add_difference('field-parameter-differ', table_name, field.name, model_type, db_type) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
283 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
284 |
@transaction.commit_manually |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
285 |
def find_differences(self): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
286 |
cur_app_label = None |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
287 |
for app_model in self.app_models: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
288 |
meta = app_model._meta |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
289 |
table_name = meta.db_table |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
290 |
app_label = meta.app_label |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
291 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
292 |
if cur_app_label!=app_label: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
293 |
# Marker indicating start of difference scan for this table_name |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
294 |
self.add_app_model_marker(app_label, app_model.__name__) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
295 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
296 |
#if not table_name in self.django_tables: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
297 |
if not table_name in self.db_tables: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
298 |
# Table is missing from database |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
299 |
self.add_difference('table-missing-in-db', table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
300 |
continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
301 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
302 |
table_indexes = self.introspection.get_indexes(self.cursor, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
303 |
fieldmap = dict([(field.db_column or field.get_attname(), field) for field in meta.fields]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
304 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
305 |
# add ordering field if model uses order_with_respect_to |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
306 |
if meta.order_with_respect_to: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
307 |
fieldmap['_order'] = ORDERING_FIELD |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
308 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
309 |
try: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
310 |
table_description = self.introspection.get_table_description(self.cursor, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
311 |
except Exception, e: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
312 |
model_diffs.append((app_model.__name__, [str(e).strip()])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
313 |
transaction.rollback() # reset transaction |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
314 |
continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
315 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
316 |
# Fields which are defined in database but not in model |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
317 |
# 1) find: 'unique-missing-in-model' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
318 |
self.find_unique_missing_in_model(meta, table_indexes, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
319 |
# 2) find: 'index-missing-in-model' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
320 |
self.find_index_missing_in_model(meta, table_indexes, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
321 |
# 3) find: 'field-missing-in-model' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
322 |
self.find_field_missing_in_model(fieldmap, table_description, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
323 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
324 |
# Fields which are defined in models but not in database |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
325 |
# 4) find: 'field-missing-in-db' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
326 |
self.find_field_missing_in_db(fieldmap, table_description, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
327 |
# 5) find: 'unique-missing-in-db' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
328 |
self.find_unique_missing_in_db(meta, table_indexes, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
329 |
# 6) find: 'index-missing-in-db' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
330 |
self.find_index_missing_in_db(meta, table_indexes, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
331 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
332 |
# Fields which have a different type or parameters |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
333 |
# 7) find: 'type-differs' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
334 |
self.find_field_type_differ(meta, table_description, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
335 |
# 8) find: 'type-parameter-differs' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
336 |
self.find_field_parameter_differ(meta, table_description, table_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
337 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
338 |
def print_diff(self, style=no_style()): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
339 |
""" print differences to stdout """ |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
340 |
if self.options.get('sql', True): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
341 |
self.print_diff_sql(style) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
342 |
else: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
343 |
self.print_diff_text(style) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
344 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
345 |
def print_diff_text(self, style): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
346 |
cur_app_label = None |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
347 |
for app_label, model_name, diffs in self.differences: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
348 |
if not diffs: continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
349 |
if not self.dense and cur_app_label != app_label: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
350 |
print style.NOTICE("+ Application:"), style.SQL_TABLE(app_label) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
351 |
cur_app_label = app_label |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
352 |
if not self.dense: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
353 |
print style.NOTICE("|-+ Differences for model:"), style.SQL_TABLE(model_name) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
354 |
for diff in diffs: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
355 |
diff_type, diff_args = diff |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
356 |
text = self.DIFF_TEXTS[diff_type] % dict((str(i), style.SQL_TABLE(e)) for i, e in enumerate(diff_args)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
357 |
text = "'".join(i%2==0 and style.ERROR_OUTPUT(e) or e for i, e in enumerate(text.split("'"))) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
358 |
if not self.dense: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
359 |
print style.NOTICE("|--+"), text |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
360 |
else: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
361 |
print style.NOTICE("App"), style.SQL_TABLE(app_name), style.NOTICE('Model'), style.SQL_TABLE(model_name), text |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
362 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
363 |
def print_diff_sql(self, style): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
364 |
cur_app_label = None |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
365 |
qn = connection.ops.quote_name |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
366 |
print style.SQL_KEYWORD("BEGIN;") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
367 |
for app_label, model_name, diffs in self.differences: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
368 |
if not diffs: continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
369 |
if not self.dense and cur_app_label != app_label: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
370 |
print style.NOTICE("-- Application: %s" % style.SQL_TABLE(app_label)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
371 |
cur_app_label = app_label |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
372 |
if not self.dense: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
373 |
print style.NOTICE("-- Model: %s" % style.SQL_TABLE(model_name)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
374 |
for diff in diffs: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
375 |
diff_type, diff_args = diff |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
376 |
text = self.DIFF_SQL[diff_type](style, qn, diff_args) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
377 |
if self.dense: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
378 |
text = text.replace("\n\t", " ") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
379 |
print text |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
380 |
print style.SQL_KEYWORD("COMMIT;") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
381 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
382 |
class GenericSQLDiff(SQLDiff): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
383 |
pass |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
384 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
385 |
class MySQLDiff(SQLDiff): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
386 |
# All the MySQL hacks together create something of a problem |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
387 |
# Fixing one bug in MySQL creates another issue. So just keep in mind |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
388 |
# that this is way unreliable for MySQL atm. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
389 |
def get_field_db_type(self, description, field=None, table_name=None): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
390 |
from MySQLdb.constants import FIELD_TYPE |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
391 |
# weird bug? in mysql db-api where it returns three times the correct value for field length |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
392 |
# if i remember correctly it had something todo with unicode strings |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
393 |
# TODO: Fix this is a more meaningful and better understood manner |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
394 |
description = list(description) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
395 |
if description[1] not in [FIELD_TYPE.TINY, FIELD_TYPE.SHORT]: # exclude tinyints from conversion. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
396 |
description[3] = description[3]/3 |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
397 |
description[4] = description[4]/3 |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
398 |
db_type = super(MySQLDiff, self).get_field_db_type(description) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
399 |
if not db_type: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
400 |
return |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
401 |
if field: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
402 |
if field.primary_key and db_type=='integer': |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
403 |
db_type += ' AUTO_INCREMENT' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
404 |
# MySQL isn't really sure about char's and varchar's like sqlite |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
405 |
field_type = self.get_field_model_type(field) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
406 |
# Fix char/varchar inconsistencies |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
407 |
if self.strip_parameters(field_type)=='char' and self.strip_parameters(db_type)=='varchar': |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
408 |
db_type = db_type.lstrip("var") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
409 |
# They like to call 'bool's 'tinyint(1)' and introspection makes that a integer |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
410 |
# just convert it back to it's proper type, a bool is a bool and nothing else. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
411 |
if db_type=='integer' and description[1]==FIELD_TYPE.TINY and description[4]==1: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
412 |
db_type = 'bool' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
413 |
if db_type=='integer' and description[1]==FIELD_TYPE.SHORT: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
414 |
db_type = 'smallint UNSIGNED' # FIXME: what about if it's not UNSIGNED ? |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
415 |
return db_type |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
416 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
417 |
class SqliteSQLDiff(SQLDiff): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
418 |
# Unique does not seem to be implied on Sqlite for Primary_key's |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
419 |
# if this is more generic among databases this might be usefull |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
420 |
# to add to the superclass's find_unique_missing_in_db method |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
421 |
def find_unique_missing_in_db(self, meta, table_indexes, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
422 |
for field in meta.fields: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
423 |
if field.unique: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
424 |
attname = field.attname |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
425 |
if attname in table_indexes and table_indexes[attname]['unique']: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
426 |
continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
427 |
if table_indexes[attname]['primary_key']: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
428 |
continue |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
429 |
self.add_difference('unique-missing-in-db', table_name, attname) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
430 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
431 |
# Finding Indexes by using the get_indexes dictionary doesn't seem to work |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
432 |
# for sqlite. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
433 |
def find_index_missing_in_db(self, meta, table_indexes, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
434 |
pass |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
435 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
436 |
def find_index_missing_in_model(self, meta, table_indexes, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
437 |
pass |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
438 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
439 |
def get_field_db_type(self, description, field=None, table_name=None): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
440 |
db_type = super(SqliteSQLDiff, self).get_field_db_type(description) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
441 |
if not db_type: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
442 |
return |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
443 |
if field: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
444 |
field_type = self.get_field_model_type(field) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
445 |
# Fix char/varchar inconsistencies |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
446 |
if self.strip_parameters(field_type)=='char' and self.strip_parameters(db_type)=='varchar': |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
447 |
db_type = db_type.lstrip("var") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
448 |
return db_type |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
449 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
450 |
class PostgresqlSQLDiff(SQLDiff): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
451 |
DATA_TYPES_REVERSE_OVERRIDE = { |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
452 |
20: 'IntegerField', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
453 |
1042: 'CharField', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
454 |
} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
455 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
456 |
# Hopefully in the future we can add constraint checking and other more |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
457 |
# advanced checks based on this database. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
458 |
SQL_LOAD_CONSTRAINTS = """ |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
459 |
SELECT nspname, relname, conname, attname, pg_get_constraintdef(pg_constraint.oid) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
460 |
FROM pg_constraint |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
461 |
INNER JOIN pg_attribute ON pg_constraint.conrelid = pg_attribute.attrelid AND pg_attribute.attnum = any(pg_constraint.conkey) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
462 |
INNER JOIN pg_class ON conrelid=pg_class.oid |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
463 |
INNER JOIN pg_namespace ON pg_namespace.oid=pg_class.relnamespace |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
464 |
ORDER BY CASE WHEN contype='f' THEN 0 ELSE 1 END,contype,nspname,relname,conname; |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
465 |
""" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
466 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
467 |
SQL_FIELD_TYPE_DIFFER = lambda self, style, qn, args: "%s %s\n\t%s %s %s %s;" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD('ALTER'), style.SQL_FIELD(qn(args[1])), style.SQL_KEYWORD("TYPE"), style.SQL_COLTYPE(args[2])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
468 |
SQL_FIELD_PARAMETER_DIFFER = lambda self, style, qn, args: "%s %s\n\t%s %s %s %s;" % (style.SQL_KEYWORD('ALTER TABLE'), style.SQL_TABLE(qn(args[0])), style.SQL_KEYWORD('ALTER'), style.SQL_FIELD(qn(args[1])), style.SQL_KEYWORD("TYPE"), style.SQL_COLTYPE(args[2])) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
469 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
470 |
def __init__(self, app_models, options): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
471 |
SQLDiff.__init__(self, app_models, options) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
472 |
self.check_constraints = {} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
473 |
self.load_constraints() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
474 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
475 |
def load_constraints(self): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
476 |
for dct in self.sql_to_dict(self.SQL_LOAD_CONSTRAINTS, []): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
477 |
key = (dct['nspname'], dct['relname'], dct['attname']) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
478 |
if 'CHECK' in dct['pg_get_constraintdef']: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
479 |
self.check_constraints[key] = dct |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
480 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
481 |
def get_field_db_type(self, description, field=None, table_name=None): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
482 |
db_type = super(PostgresqlSQLDiff, self).get_field_db_type(description) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
483 |
if not db_type: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
484 |
return |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
485 |
if field: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
486 |
if field.primary_key and db_type=='integer': |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
487 |
db_type = 'serial' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
488 |
if table_name: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
489 |
tablespace = field.db_tablespace |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
490 |
if tablespace=="": |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
491 |
tablespace = "public" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
492 |
check_constraint = self.check_constraints.get((tablespace, table_name, field.attname),{}).get('pg_get_constraintdef', None) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
493 |
if check_constraint: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
494 |
check_constraint = check_constraint.replace("((", "(") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
495 |
check_constraint = check_constraint.replace("))", ")") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
496 |
check_constraint = '("'.join([')' in e and '" '.join(e.split(" ", 1)) or e for e in check_constraint.split("(")]) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
497 |
# TODO: might be more then one constraint in definition ? |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
498 |
db_type += ' '+check_constraint |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
499 |
return db_type |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
500 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
501 |
""" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
502 |
def find_field_type_differ(self, meta, table_description, table_name): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
503 |
def callback(field, description, model_type, db_type): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
504 |
if field.primary_key and db_type=='integer': |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
505 |
db_type = 'serial' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
506 |
return model_type, db_type |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
507 |
super(PostgresqlSQLDiff, self).find_field_type_differs(meta, table_description, table_name, callback) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
508 |
""" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
509 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
510 |
DATABASE_SQLDIFF_CLASSES = { |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
511 |
'postgresql_psycopg2' : PostgresqlSQLDiff, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
512 |
'postgresql': PostgresqlSQLDiff, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
513 |
'mysql': MySQLDiff, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
514 |
'sqlite3': SqliteSQLDiff, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
515 |
'oracle': GenericSQLDiff |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
516 |
} |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
517 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
518 |
class Command(BaseCommand): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
519 |
option_list = BaseCommand.option_list + ( |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
520 |
make_option('--all-applications', '-a', action='store_true', dest='all_applications', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
521 |
help="Automaticly include all application from INSTALLED_APPS."), |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
522 |
make_option('--not-only-existing', '-e', action='store_false', dest='only_existing', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
523 |
help="Check all tables that exist in the database, not only tables that should exist based on models."), |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
524 |
make_option('--dense-output', '-d', action='store_true', dest='dense_output', |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
525 |
help="Shows the output in dense format, normally output is spreaded over multiple lines."), |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
526 |
make_option('--output_text', '-t', action='store_false', dest='sql', default=True, |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
527 |
help="Outputs the differences as descriptive text instead of SQL"), |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
528 |
) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
529 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
530 |
help = """Prints the (approximated) difference between models and fields in the database for the given app name(s). |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
531 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
532 |
It indicates how columns in the database are different from the sql that would |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
533 |
be generated by Django. This command is not a database migration tool. (Though |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
534 |
it can certainly help) It's purpose is to show the current differences as a way |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
535 |
to check/debug ur models compared to the real database tables and columns.""" |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
536 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
537 |
output_transaction = False |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
538 |
args = '<appname appname ...>' |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
539 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
540 |
def handle(self, *app_labels, **options): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
541 |
from django.db import models |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
542 |
from django.conf import settings |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
543 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
544 |
if settings.DATABASE_ENGINE =='dummy': |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
545 |
# This must be the "dummy" database backend, which means the user |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
546 |
# hasn't set DATABASE_ENGINE. |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
547 |
raise CommandError("Django doesn't know which syntax to use for your SQL statements,\n" + |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
548 |
"because you haven't specified the DATABASE_ENGINE setting.\n" + |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
549 |
"Edit your settings file and change DATABASE_ENGINE to something like 'postgresql' or 'mysql'.") |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
550 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
551 |
if options.get('all_applications', False): |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
552 |
app_models = models.get_models() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
553 |
else: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
554 |
if not app_labels: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
555 |
raise CommandError('Enter at least one appname.') |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
556 |
try: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
557 |
app_list = [models.get_app(app_label) for app_label in app_labels] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
558 |
except (models.ImproperlyConfigured, ImportError), e: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
559 |
raise CommandError("%s. Are you sure your INSTALLED_APPS setting is correct?" % e) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
560 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
561 |
app_models = [] |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
562 |
for app in app_list: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
563 |
app_models.extend(models.get_models(app)) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
564 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
565 |
if not app_models: |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
566 |
raise CommandError('Unable to execute sqldiff no models founds.') |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
567 |
|
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
568 |
cls = DATABASE_SQLDIFF_CLASSES.get(settings.DATABASE_ENGINE, GenericSQLDiff) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
569 |
sqldiff_instance = cls(app_models, options) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
570 |
sqldiff_instance.find_differences() |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
571 |
sqldiff_instance.print_diff(self.style) |
|
526ebd3988b0
replace pocketfilms occurence by blinkster
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
572 |
return |