34
38
def __init__(self, diff, declarative=False):
36
40
self.declarative = declarative
37
# is there an easier way to get this?
38
dialectModule = sys.modules[self.diff.conn.dialect.__module__]
39
self.colTypeMappings = dict((v, k) for k, v in \
40
dialectModule.colspecs.items())
42
42
def column_repr(self, col):
63
63
# crs: not sure if this is good idea, but it gets rid of extra
65
65
name = col.name.encode('utf8')
66
type = self.colTypeMappings.get(col.type.__class__, None)
68
# Make the column type be an instance of this type.
71
# We must already be a model type, no need to map from the
72
# database-specific types.
68
for cls in col.type.__class__.__mro__:
69
if cls.__module__ == 'sqlalchemy.types' and \
70
not cls.__name__.isupper():
71
if cls is not type_.__class__:
78
78
'constraints': ', '.join([repr(cn) for cn in col.constraints]),
79
79
'args': ks and ks or ''}
127
127
def toUpgradeDowngradePython(self, indent=' '):
128
128
''' Assume model is most current and database is out-of-date. '''
130
decls = ['meta = MetaData(migrate_engine)']
129
decls = ['from migrate.changeset import schema',
131
131
for table in self.diff.tablesMissingInModel + \
132
self.diff.tablesMissingInDatabase:
132
self.diff.tablesMissingInDatabase + \
133
self.diff.tablesWithDiff:
133
134
decls.extend(self.getTableDefn(table))
135
136
upgradeCommands, downgradeCommands = [], []
143
144
upgradeCommands.append("%(table)s.create()" % {'table': tableName})
144
145
downgradeCommands.append("%(table)s.drop()" % {'table': tableName})
147
for modelTable in self.diff.tablesWithDiff:
148
dbTable = self.diff.reflected_model.tables[modelTable.name]
149
tableName = modelTable.name
150
missingInDatabase, missingInModel, diffDecl = \
151
self.diff.colDiffs[tableName]
152
for col in missingInDatabase:
153
upgradeCommands.append('%s.columns[%r].create()' % (
154
modelTable, col.name))
155
downgradeCommands.append('%s.columns[%r].drop()' % (
156
modelTable, col.name))
157
for col in missingInModel:
158
upgradeCommands.append('%s.columns[%r].drop()' % (
159
modelTable, col.name))
160
downgradeCommands.append('%s.columns[%r].create()' % (
161
modelTable, col.name))
162
for modelCol, databaseCol, modelDecl, databaseDecl in diffDecl:
163
upgradeCommands.append(
164
'assert False, "Can\'t alter columns: %s:%s=>%s"',
165
modelTable, modelCol.name, databaseCol.name)
166
downgradeCommands.append(
167
'assert False, "Can\'t alter columns: %s:%s=>%s"',
168
modelTable, modelCol.name, databaseCol.name)
169
pre_command = ' meta.bind = migrate_engine'
147
172
'\n'.join(decls),
148
'\n'.join(['%s%s' % (indent, line) for line in upgradeCommands]),
149
'\n'.join(['%s%s' % (indent, line) for line in downgradeCommands]))
173
'\n'.join([pre_command] + ['%s%s' % (indent, line) for line in upgradeCommands]),
174
'\n'.join([pre_command] + ['%s%s' % (indent, line) for line in downgradeCommands]))
151
176
def applyModel(self):
152
177
"""Apply model to current database."""
153
# Yuck! We have to import from changeset to apply the
154
# monkey-patch to allow column adding/dropping.
155
from migrate.changeset import schema
157
179
def dbCanHandleThisChange(missingInDatabase, missingInModel, diffDecl):
158
180
if missingInDatabase and not missingInModel and not diffDecl: