Mercurial > kallithea
annotate rhodecode/lib/dbmigrate/migrate/versioning/genmodel.py @ 833:9753e0907827 beta
added dbmigrate package, added model changes
moved out upgrade db command to that package
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sat, 11 Dec 2010 01:54:12 +0100 |
parents | |
children | 08d2dcd71666 |
rev | line source |
---|---|
833
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
1 """ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
2 Code to generate a Python model from a database or differences |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
3 between a model and database. |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
4 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
5 Some of this is borrowed heavily from the AutoCode project at: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
6 http://code.google.com/p/sqlautocode/ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
7 """ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
8 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
9 import sys |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
10 import logging |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
11 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
12 import sqlalchemy |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
13 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
14 import migrate |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
15 import migrate.changeset |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
16 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
17 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
18 log = logging.getLogger(__name__) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
19 HEADER = """ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
20 ## File autogenerated by genmodel.py |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
21 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
22 from sqlalchemy import * |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
23 meta = MetaData() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
24 """ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
25 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
26 DECLARATIVE_HEADER = """ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
27 ## File autogenerated by genmodel.py |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
28 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
29 from sqlalchemy import * |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
30 from sqlalchemy.ext import declarative |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
31 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
32 Base = declarative.declarative_base() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
33 """ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
34 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
35 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
36 class ModelGenerator(object): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
37 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
38 def __init__(self, diff, engine, declarative=False): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
39 self.diff = diff |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
40 self.engine = engine |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
41 self.declarative = declarative |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
42 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
43 def column_repr(self, col): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
44 kwarg = [] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
45 if col.key != col.name: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
46 kwarg.append('key') |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
47 if col.primary_key: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
48 col.primary_key = True # otherwise it dumps it as 1 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
49 kwarg.append('primary_key') |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
50 if not col.nullable: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
51 kwarg.append('nullable') |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
52 if col.onupdate: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
53 kwarg.append('onupdate') |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
54 if col.default: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
55 if col.primary_key: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
56 # I found that PostgreSQL automatically creates a |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
57 # default value for the sequence, but let's not show |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
58 # that. |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
59 pass |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
60 else: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
61 kwarg.append('default') |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
62 ks = ', '.join('%s=%r' % (k, getattr(col, k)) for k in kwarg) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
63 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
64 # crs: not sure if this is good idea, but it gets rid of extra |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
65 # u'' |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
66 name = col.name.encode('utf8') |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
67 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
68 type_ = col.type |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
69 for cls in col.type.__class__.__mro__: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
70 if cls.__module__ == 'sqlalchemy.types' and \ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
71 not cls.__name__.isupper(): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
72 if cls is not type_.__class__: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
73 type_ = cls() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
74 break |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
75 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
76 data = { |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
77 'name': name, |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
78 'type': type_, |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
79 'constraints': ', '.join([repr(cn) for cn in col.constraints]), |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
80 'args': ks and ks or ''} |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
81 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
82 if data['constraints']: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
83 if data['args']: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
84 data['args'] = ',' + data['args'] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
85 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
86 if data['constraints'] or data['args']: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
87 data['maybeComma'] = ',' |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
88 else: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
89 data['maybeComma'] = '' |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
90 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
91 commonStuff = """ %(maybeComma)s %(constraints)s %(args)s)""" % data |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
92 commonStuff = commonStuff.strip() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
93 data['commonStuff'] = commonStuff |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
94 if self.declarative: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
95 return """%(name)s = Column(%(type)r%(commonStuff)s""" % data |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
96 else: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
97 return """Column(%(name)r, %(type)r%(commonStuff)s""" % data |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
98 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
99 def getTableDefn(self, table): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
100 out = [] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
101 tableName = table.name |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
102 if self.declarative: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
103 out.append("class %(table)s(Base):" % {'table': tableName}) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
104 out.append(" __tablename__ = '%(table)s'" % {'table': tableName}) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
105 for col in table.columns: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
106 out.append(" %s" % self.column_repr(col)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
107 else: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
108 out.append("%(table)s = Table('%(table)s', meta," % \ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
109 {'table': tableName}) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
110 for col in table.columns: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
111 out.append(" %s," % self.column_repr(col)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
112 out.append(")") |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
113 return out |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
114 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
115 def _get_tables(self,missingA=False,missingB=False,modified=False): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
116 to_process = [] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
117 for bool_,names,metadata in ( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
118 (missingA,self.diff.tables_missing_from_A,self.diff.metadataB), |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
119 (missingB,self.diff.tables_missing_from_B,self.diff.metadataA), |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
120 (modified,self.diff.tables_different,self.diff.metadataA), |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
121 ): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
122 if bool_: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
123 for name in names: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
124 yield metadata.tables.get(name) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
125 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
126 def toPython(self): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
127 """Assume database is current and model is empty.""" |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
128 out = [] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
129 if self.declarative: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
130 out.append(DECLARATIVE_HEADER) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
131 else: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
132 out.append(HEADER) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
133 out.append("") |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
134 for table in self._get_tables(missingA=True): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
135 out.extend(self.getTableDefn(table)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
136 out.append("") |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
137 return '\n'.join(out) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
138 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
139 def toUpgradeDowngradePython(self, indent=' '): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
140 ''' Assume model is most current and database is out-of-date. ''' |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
141 decls = ['from migrate.changeset import schema', |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
142 'meta = MetaData()'] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
143 for table in self._get_tables( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
144 missingA=True,missingB=True,modified=True |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
145 ): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
146 decls.extend(self.getTableDefn(table)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
147 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
148 upgradeCommands, downgradeCommands = [], [] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
149 for tableName in self.diff.tables_missing_from_A: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
150 upgradeCommands.append("%(table)s.drop()" % {'table': tableName}) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
151 downgradeCommands.append("%(table)s.create()" % \ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
152 {'table': tableName}) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
153 for tableName in self.diff.tables_missing_from_B: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
154 upgradeCommands.append("%(table)s.create()" % {'table': tableName}) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
155 downgradeCommands.append("%(table)s.drop()" % {'table': tableName}) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
156 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
157 for tableName in self.diff.tables_different: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
158 dbTable = self.diff.metadataB.tables[tableName] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
159 missingInDatabase, missingInModel, diffDecl = \ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
160 self.diff.colDiffs[tableName] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
161 for col in missingInDatabase: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
162 upgradeCommands.append('%s.columns[%r].create()' % ( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
163 modelTable, col.name)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
164 downgradeCommands.append('%s.columns[%r].drop()' % ( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
165 modelTable, col.name)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
166 for col in missingInModel: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
167 upgradeCommands.append('%s.columns[%r].drop()' % ( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
168 modelTable, col.name)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
169 downgradeCommands.append('%s.columns[%r].create()' % ( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
170 modelTable, col.name)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
171 for modelCol, databaseCol, modelDecl, databaseDecl in diffDecl: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
172 upgradeCommands.append( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
173 'assert False, "Can\'t alter columns: %s:%s=>%s"', |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
174 modelTable, modelCol.name, databaseCol.name) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
175 downgradeCommands.append( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
176 'assert False, "Can\'t alter columns: %s:%s=>%s"', |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
177 modelTable, modelCol.name, databaseCol.name) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
178 pre_command = ' meta.bind = migrate_engine' |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
179 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
180 return ( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
181 '\n'.join(decls), |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
182 '\n'.join([pre_command] + ['%s%s' % (indent, line) for line in upgradeCommands]), |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
183 '\n'.join([pre_command] + ['%s%s' % (indent, line) for line in downgradeCommands])) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
184 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
185 def _db_can_handle_this_change(self,td): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
186 if (td.columns_missing_from_B |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
187 and not td.columns_missing_from_A |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
188 and not td.columns_different): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
189 # Even sqlite can handle this. |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
190 return True |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
191 else: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
192 return not self.engine.url.drivername.startswith('sqlite') |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
193 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
194 def applyModel(self): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
195 """Apply model to current database.""" |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
196 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
197 meta = sqlalchemy.MetaData(self.engine) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
198 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
199 for table in self._get_tables(missingA=True): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
200 table = table.tometadata(meta) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
201 table.drop() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
202 for table in self._get_tables(missingB=True): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
203 table = table.tometadata(meta) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
204 table.create() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
205 for modelTable in self._get_tables(modified=True): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
206 tableName = modelTable.name |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
207 modelTable = modelTable.tometadata(meta) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
208 dbTable = self.diff.metadataB.tables[tableName] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
209 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
210 td = self.diff.tables_different[tableName] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
211 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
212 if self._db_can_handle_this_change(td): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
213 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
214 for col in td.columns_missing_from_B: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
215 modelTable.columns[col].create() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
216 for col in td.columns_missing_from_A: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
217 dbTable.columns[col].drop() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
218 # XXX handle column changes here. |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
219 else: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
220 # Sqlite doesn't support drop column, so you have to |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
221 # do more: create temp table, copy data to it, drop |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
222 # old table, create new table, copy data back. |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
223 # |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
224 # I wonder if this is guaranteed to be unique? |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
225 tempName = '_temp_%s' % modelTable.name |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
226 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
227 def getCopyStatement(): |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
228 preparer = self.engine.dialect.preparer |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
229 commonCols = [] |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
230 for modelCol in modelTable.columns: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
231 if modelCol.name in dbTable.columns: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
232 commonCols.append(modelCol.name) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
233 commonColsStr = ', '.join(commonCols) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
234 return 'INSERT INTO %s (%s) SELECT %s FROM %s' % \ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
235 (tableName, commonColsStr, commonColsStr, tempName) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
236 |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
237 # Move the data in one transaction, so that we don't |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
238 # leave the database in a nasty state. |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
239 connection = self.engine.connect() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
240 trans = connection.begin() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
241 try: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
242 connection.execute( |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
243 'CREATE TEMPORARY TABLE %s as SELECT * from %s' % \ |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
244 (tempName, modelTable.name)) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
245 # make sure the drop takes place inside our |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
246 # transaction with the bind parameter |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
247 modelTable.drop(bind=connection) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
248 modelTable.create(bind=connection) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
249 connection.execute(getCopyStatement()) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
250 connection.execute('DROP TABLE %s' % tempName) |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
251 trans.commit() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
252 except: |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
253 trans.rollback() |
9753e0907827
added dbmigrate package, added model changes
Marcin Kuzminski <marcin@python-works.com>
parents:
diff
changeset
|
254 raise |