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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
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