##// END OF EJS Templates
updated sqlalchemy migrate to latest version
marcink -
r1061:9bb609d1 beta
parent child Browse files
Show More
@@ -2,7 +2,7 b''
2 2 Firebird database specific implementations of changeset classes.
3 3 """
4 4 from sqlalchemy.databases import firebird as sa_base
5
5 from sqlalchemy.schema import PrimaryKeyConstraint
6 6 from rhodecode.lib.dbmigrate.migrate import exceptions
7 7 from rhodecode.lib.dbmigrate.migrate.changeset import ansisql, SQLA_06
8 8
@@ -27,13 +27,32 b' class FBColumnDropper(ansisql.ANSIColumn'
27 27 if column.table.primary_key.columns.contains_column(column):
28 28 column.table.primary_key.drop()
29 29 # TODO: recreate primary key if it references more than this column
30 if column.unique or getattr(column, 'unique_name', None):
30
31 for index in column.table.indexes:
32 # "column in index.columns" causes problems as all
33 # column objects compare equal and return a SQL expression
34 if column.name in [col.name for col in index.columns]:
35 index.drop()
36 # TODO: recreate index if it references more than this column
37
31 38 for cons in column.table.constraints:
32 if cons.contains_column(column):
33 cons.drop()
39 if isinstance(cons,PrimaryKeyConstraint):
40 # will be deleted only when the column its on
41 # is deleted!
42 continue
43
44 if SQLA_06:
45 should_drop = column.name in cons.columns
46 else:
47 should_drop = cons.contains_column(column) and cons.name
48 if should_drop:
49 self.start_alter_table(column)
50 self.append("DROP CONSTRAINT ")
51 self.append(self.preparer.format_constraint(cons))
52 self.execute()
34 53 # TODO: recreate unique constraint if it refenrences more than this column
35 54
36 table = self.start_alter_table(column)
55 self.start_alter_table(column)
37 56 self.append('DROP %s' % self.preparer.format_column(column))
38 57 self.execute()
39 58
@@ -80,10 +80,17 b' class SQLiteColumnDropper(SQLiteHelper, '
80 80 """SQLite ColumnDropper"""
81 81
82 82 def _modify_table(self, table, column, delta):
83
83 84 columns = ' ,'.join(map(self.preparer.format_column, table.columns))
84 85 return 'INSERT INTO %(table_name)s SELECT ' + columns + \
85 86 ' from migration_tmp'
86 87
88 def visit_column(self,column):
89 # For SQLite, we *have* to remove the column here so the table
90 # is re-created properly.
91 column.remove_from_table(column.table,unset_table=False)
92 super(SQLiteColumnDropper,self).visit_column(column)
93
87 94
88 95 class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger):
89 96 """SQLite SchemaChanger"""
@@ -29,9 +29,6 b' from rhodecode.lib.dbmigrate.migrate.cha'
29 29 'ColumnDelta',
30 30 ]
31 31
32 DEFAULT_ALTER_METADATA = True
33
34
35 32 def create_column(column, table=None, *p, **kw):
36 33 """Create a column, given the table.
37 34
@@ -109,19 +106,11 b' def alter_column(*p, **k):'
109 106 The :class:`~sqlalchemy.engine.base.Engine` to use for table
110 107 reflection and schema alterations.
111 108
112 :param alter_metadata:
113 If `True`, which is the default, the
114 :class:`~sqlalchemy.schema.Column` will also modified.
115 If `False`, the :class:`~sqlalchemy.schema.Column` will be left
116 as it was.
117
118 109 :returns: A :class:`ColumnDelta` instance representing the change.
119 110
120 111
121 112 """
122 113
123 k.setdefault('alter_metadata', DEFAULT_ALTER_METADATA)
124
125 114 if 'table' not in k and isinstance(p[0], sqlalchemy.Column):
126 115 k['table'] = p[0].table
127 116 if 'engine' not in k:
@@ -135,6 +124,12 b' def alter_column(*p, **k):'
135 124 MigrateDeprecationWarning
136 125 )
137 126 engine = k['engine']
127
128 # enough tests seem to break when metadata is always altered
129 # that this crutch has to be left in until they can be sorted
130 # out
131 k['alter_metadata']=True
132
138 133 delta = ColumnDelta(*p, **k)
139 134
140 135 visitorcallable = get_engine_visitor(engine, 'schemachanger')
@@ -188,11 +183,10 b' class ColumnDelta(DictMixin, sqlalchemy.'
188 183 :param table: Table at which current Column should be bound to.\
189 184 If table name is given, reflection will be used.
190 185 :type table: string or Table instance
191 :param alter_metadata: If True, it will apply changes to metadata.
192 :type alter_metadata: bool
193 :param metadata: If `alter_metadata` is true, \
194 metadata is used to reflect table names into
195 :type metadata: :class:`MetaData` instance
186
187 :param metadata: A :class:`MetaData` instance to store
188 reflected table names
189
196 190 :param engine: When reflecting tables, either engine or metadata must \
197 191 be specified to acquire engine object.
198 192 :type engine: :class:`Engine` instance
@@ -213,7 +207,11 b' class ColumnDelta(DictMixin, sqlalchemy.'
213 207 __visit_name__ = 'column'
214 208
215 209 def __init__(self, *p, **kw):
210 # 'alter_metadata' is not a public api. It exists purely
211 # as a crutch until the tests that fail when 'alter_metadata'
212 # behaviour always happens can be sorted out
216 213 self.alter_metadata = kw.pop("alter_metadata", False)
214
217 215 self.meta = kw.pop("metadata", None)
218 216 self.engine = kw.pop("engine", None)
219 217
@@ -237,8 +235,10 b' class ColumnDelta(DictMixin, sqlalchemy.'
237 235 self.apply_diffs(diffs)
238 236
239 237 def __repr__(self):
240 return '<ColumnDelta altermetadata=%r, %s>' % (self.alter_metadata,
241 super(ColumnDelta, self).__repr__())
238 return '<ColumnDelta altermetadata=%r, %s>' % (
239 self.alter_metadata,
240 super(ColumnDelta, self).__repr__()
241 )
242 242
243 243 def __getitem__(self, key):
244 244 if key not in self.keys():
@@ -395,7 +395,6 b' class ColumnDelta(DictMixin, sqlalchemy.'
395 395 self._table = table
396 396 if not self.alter_metadata:
397 397 self._table.meta = sqlalchemy.MetaData(bind=self._table.bind)
398
399 398 def _get_result_column(self):
400 399 return getattr(self, '_result_column', None)
401 400
@@ -456,19 +455,15 b' class ChangesetTable(object):'
456 455
457 456 :param name: New name of the table.
458 457 :type name: string
459 :param alter_metadata: If True, table will be removed from metadata
460 :type alter_metadata: bool
461 458 :param connection: reuse connection istead of creating new one.
462 459 :type connection: :class:`sqlalchemy.engine.base.Connection` instance
463 460 """
464 self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
465 461 engine = self.bind
466 462 self.new_name = name
467 463 visitorcallable = get_engine_visitor(engine, 'schemachanger')
468 464 run_single_visitor(engine, visitorcallable, self, connection, **kwargs)
469 465
470 466 # Fix metadata registration
471 if self.alter_metadata:
472 467 self.name = name
473 468 self.deregister()
474 469 self._set_parent(self.metadata)
@@ -510,7 +505,6 b' class ChangesetColumn(object):'
510 505 `~migrate.changeset.constraint.UniqueConstraint` on this column.
511 506 :param primary_key_name: Creates :class:\
512 507 `~migrate.changeset.constraint.PrimaryKeyConstraint` on this column.
513 :param alter_metadata: If True, column will be added to table object.
514 508 :param populate_default: If True, created column will be \
515 509 populated with defaults
516 510 :param connection: reuse connection istead of creating new one.
@@ -518,21 +512,18 b' populated with defaults'
518 512 :type index_name: string
519 513 :type unique_name: string
520 514 :type primary_key_name: string
521 :type alter_metadata: bool
522 515 :type populate_default: bool
523 516 :type connection: :class:`sqlalchemy.engine.base.Connection` instance
524 517
525 518 :returns: self
526 519 """
527 520 self.populate_default = populate_default
528 self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
529 521 self.index_name = index_name
530 522 self.unique_name = unique_name
531 523 self.primary_key_name = primary_key_name
532 524 for cons in ('index_name', 'unique_name', 'primary_key_name'):
533 525 self._check_sanity_constraints(cons)
534 526
535 if self.alter_metadata:
536 527 self.add_to_table(table)
537 528 engine = self.table.bind
538 529 visitorcallable = get_engine_visitor(engine, 'columngenerator')
@@ -550,20 +541,15 b' populated with defaults'
550 541
551 542 ``ALTER TABLE DROP COLUMN``, for most databases.
552 543
553 :param alter_metadata: If True, column will be removed from table object.
554 :type alter_metadata: bool
555 544 :param connection: reuse connection istead of creating new one.
556 545 :type connection: :class:`sqlalchemy.engine.base.Connection` instance
557 546 """
558 self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
559 547 if table is not None:
560 548 self.table = table
561 549 engine = self.table.bind
562 if self.alter_metadata:
563 self.remove_from_table(self.table, unset_table=False)
564 550 visitorcallable = get_engine_visitor(engine, 'columndropper')
565 551 engine._run_visitor(visitorcallable, self, connection, **kwargs)
566 if self.alter_metadata:
552 self.remove_from_table(self.table, unset_table=False)
567 553 self.table = None
568 554 return self
569 555
@@ -643,17 +629,13 b' class ChangesetIndex(object):'
643 629
644 630 :param name: New name of the Index.
645 631 :type name: string
646 :param alter_metadata: If True, Index object will be altered.
647 :type alter_metadata: bool
648 632 :param connection: reuse connection istead of creating new one.
649 633 :type connection: :class:`sqlalchemy.engine.base.Connection` instance
650 634 """
651 self.alter_metadata = kwargs.pop('alter_metadata', DEFAULT_ALTER_METADATA)
652 635 engine = self.table.bind
653 636 self.new_name = name
654 637 visitorcallable = get_engine_visitor(engine, 'schemachanger')
655 638 engine._run_visitor(visitorcallable, self, connection, **kwargs)
656 if self.alter_metadata:
657 639 self.name = name
658 640
659 641
@@ -169,11 +169,11 b' class ModelGenerator(object):'
169 169 modelTable, col.name))
170 170 for modelCol, databaseCol, modelDecl, databaseDecl in diffDecl:
171 171 upgradeCommands.append(
172 'assert False, "Can\'t alter columns: %s:%s=>%s"',
173 modelTable, modelCol.name, databaseCol.name)
172 'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
173 modelTable, modelCol.name, databaseCol.name))
174 174 downgradeCommands.append(
175 'assert False, "Can\'t alter columns: %s:%s=>%s"',
176 modelTable, modelCol.name, databaseCol.name)
175 'assert False, "Can\'t alter columns: %s:%s=>%s"' % (
176 modelTable, modelCol.name, databaseCol.name))
177 177 pre_command = ' meta.bind = migrate_engine'
178 178
179 179 return (
@@ -4,6 +4,7 b''
4 4 import shutil
5 5 import warnings
6 6 import logging
7 import inspect
7 8 from StringIO import StringIO
8 9
9 10 from rhodecode.lib.dbmigrate import migrate
@@ -136,12 +137,12 b' class PythonScript(base.BaseScript):'
136 137 funcname = base.operations[op]
137 138 script_func = self._func(funcname)
138 139
139 try:
140 # check for old way of using engine
141 if not inspect.getargspec(script_func)[0]:
142 raise TypeError("upgrade/downgrade functions must accept engine"
143 " parameter (since version 0.5.4)")
144
140 145 script_func(engine)
141 except TypeError:
142 warnings.warn("upgrade/downgrade functions must accept engine"
143 " parameter (since version > 0.5.4)", MigrateDeprecationWarning)
144 raise
145 146
146 147 @property
147 148 def module(self):
@@ -18,6 +18,7 b' class SqlScript(base.BaseScript):'
18 18
19 19 :returns: :class:`SqlScript instance <migrate.versioning.script.sql.SqlScript>`"""
20 20 cls.require_notfound(path)
21
21 22 src = Template(opts.pop('templates_path', None)).get_sql_script(theme=opts.pop('templates_theme', None))
22 23 shutil.copy(src, path)
23 24 return cls(path)
@@ -77,8 +77,7 b' def main(argv=None, **kwargs):'
77 77 %s
78 78
79 79 Enter "%%prog help COMMAND" for information on a particular command.
80 """ % '\n\t'.join(["%s - %s" % (command.ljust(28),
81 api.command_desc.get(command)) for command in commands])
80 """ % '\n\t'.join(["%s - %s" % (command.ljust(28), api.command_desc.get(command)) for command in commands])
82 81
83 82 parser = PassiveOptionParser(usage=usage)
84 83 parser.add_option("-d", "--debug",
General Comments 0
You need to be logged in to leave comments. Login now