Mercurial > kallithea
comparison rhodecode/lib/dbmigrate/migrate/changeset/databases/sqlite.py @ 833:9753e0907827 beta
added dbmigrate package, added model changes
moved out upgrade db command to that package
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Sat, 11 Dec 2010 01:54:12 +0100 |
parents | |
children | 08d2dcd71666 |
comparison
equal
deleted
inserted
replaced
832:634596f81cfd | 833:9753e0907827 |
---|---|
1 """ | |
2 `SQLite`_ database specific implementations of changeset classes. | |
3 | |
4 .. _`SQLite`: http://www.sqlite.org/ | |
5 """ | |
6 from UserDict import DictMixin | |
7 from copy import copy | |
8 | |
9 from sqlalchemy.databases import sqlite as sa_base | |
10 | |
11 from migrate import exceptions | |
12 from migrate.changeset import ansisql, SQLA_06 | |
13 | |
14 | |
15 if not SQLA_06: | |
16 SQLiteSchemaGenerator = sa_base.SQLiteSchemaGenerator | |
17 else: | |
18 SQLiteSchemaGenerator = sa_base.SQLiteDDLCompiler | |
19 | |
20 class SQLiteCommon(object): | |
21 | |
22 def _not_supported(self, op): | |
23 raise exceptions.NotSupportedError("SQLite does not support " | |
24 "%s; see http://www.sqlite.org/lang_altertable.html" % op) | |
25 | |
26 | |
27 class SQLiteHelper(SQLiteCommon): | |
28 | |
29 def recreate_table(self,table,column=None,delta=None): | |
30 table_name = self.preparer.format_table(table) | |
31 | |
32 # we remove all indexes so as not to have | |
33 # problems during copy and re-create | |
34 for index in table.indexes: | |
35 index.drop() | |
36 | |
37 self.append('ALTER TABLE %s RENAME TO migration_tmp' % table_name) | |
38 self.execute() | |
39 | |
40 insertion_string = self._modify_table(table, column, delta) | |
41 | |
42 table.create() | |
43 self.append(insertion_string % {'table_name': table_name}) | |
44 self.execute() | |
45 self.append('DROP TABLE migration_tmp') | |
46 self.execute() | |
47 | |
48 def visit_column(self, delta): | |
49 if isinstance(delta, DictMixin): | |
50 column = delta.result_column | |
51 table = self._to_table(delta.table) | |
52 else: | |
53 column = delta | |
54 table = self._to_table(column.table) | |
55 self.recreate_table(table,column,delta) | |
56 | |
57 class SQLiteColumnGenerator(SQLiteSchemaGenerator, | |
58 ansisql.ANSIColumnGenerator, | |
59 # at the end so we get the normal | |
60 # visit_column by default | |
61 SQLiteHelper, | |
62 SQLiteCommon | |
63 ): | |
64 """SQLite ColumnGenerator""" | |
65 | |
66 def _modify_table(self, table, column, delta): | |
67 columns = ' ,'.join(map( | |
68 self.preparer.format_column, | |
69 [c for c in table.columns if c.name!=column.name])) | |
70 return ('INSERT INTO %%(table_name)s (%(cols)s) ' | |
71 'SELECT %(cols)s from migration_tmp')%{'cols':columns} | |
72 | |
73 def visit_column(self,column): | |
74 if column.foreign_keys: | |
75 SQLiteHelper.visit_column(self,column) | |
76 else: | |
77 super(SQLiteColumnGenerator,self).visit_column(column) | |
78 | |
79 class SQLiteColumnDropper(SQLiteHelper, ansisql.ANSIColumnDropper): | |
80 """SQLite ColumnDropper""" | |
81 | |
82 def _modify_table(self, table, column, delta): | |
83 columns = ' ,'.join(map(self.preparer.format_column, table.columns)) | |
84 return 'INSERT INTO %(table_name)s SELECT ' + columns + \ | |
85 ' from migration_tmp' | |
86 | |
87 | |
88 class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger): | |
89 """SQLite SchemaChanger""" | |
90 | |
91 def _modify_table(self, table, column, delta): | |
92 return 'INSERT INTO %(table_name)s SELECT * from migration_tmp' | |
93 | |
94 def visit_index(self, index): | |
95 """Does not support ALTER INDEX""" | |
96 self._not_supported('ALTER INDEX') | |
97 | |
98 | |
99 class SQLiteConstraintGenerator(ansisql.ANSIConstraintGenerator, SQLiteHelper, SQLiteCommon): | |
100 | |
101 def visit_migrate_primary_key_constraint(self, constraint): | |
102 tmpl = "CREATE UNIQUE INDEX %s ON %s ( %s )" | |
103 cols = ', '.join(map(self.preparer.format_column, constraint.columns)) | |
104 tname = self.preparer.format_table(constraint.table) | |
105 name = self.get_constraint_name(constraint) | |
106 msg = tmpl % (name, tname, cols) | |
107 self.append(msg) | |
108 self.execute() | |
109 | |
110 def _modify_table(self, table, column, delta): | |
111 return 'INSERT INTO %(table_name)s SELECT * from migration_tmp' | |
112 | |
113 def visit_migrate_foreign_key_constraint(self, *p, **k): | |
114 self.recreate_table(p[0].table) | |
115 | |
116 def visit_migrate_unique_constraint(self, *p, **k): | |
117 self.recreate_table(p[0].table) | |
118 | |
119 | |
120 class SQLiteConstraintDropper(ansisql.ANSIColumnDropper, | |
121 SQLiteCommon, | |
122 ansisql.ANSIConstraintCommon): | |
123 | |
124 def visit_migrate_primary_key_constraint(self, constraint): | |
125 tmpl = "DROP INDEX %s " | |
126 name = self.get_constraint_name(constraint) | |
127 msg = tmpl % (name) | |
128 self.append(msg) | |
129 self.execute() | |
130 | |
131 def visit_migrate_foreign_key_constraint(self, *p, **k): | |
132 self._not_supported('ALTER TABLE DROP CONSTRAINT') | |
133 | |
134 def visit_migrate_check_constraint(self, *p, **k): | |
135 self._not_supported('ALTER TABLE DROP CONSTRAINT') | |
136 | |
137 def visit_migrate_unique_constraint(self, *p, **k): | |
138 self._not_supported('ALTER TABLE DROP CONSTRAINT') | |
139 | |
140 | |
141 # TODO: technically primary key is a NOT NULL + UNIQUE constraint, should add NOT NULL to index | |
142 | |
143 class SQLiteDialect(ansisql.ANSIDialect): | |
144 columngenerator = SQLiteColumnGenerator | |
145 columndropper = SQLiteColumnDropper | |
146 schemachanger = SQLiteSchemaChanger | |
147 constraintgenerator = SQLiteConstraintGenerator | |
148 constraintdropper = SQLiteConstraintDropper |