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