make migrate.changeset.databases PEP-8 clean and add it to the API docs
This commit is contained in:
parent
728b677e56
commit
eb00570991
45
docs/api.rst
45
docs/api.rst
@ -9,13 +9,54 @@ Module :mod:`migrate.changeset`
|
|||||||
:members:
|
:members:
|
||||||
:synopsis: Database changeset management
|
:synopsis: Database changeset management
|
||||||
|
|
||||||
Module :mod:`migrate.changeset.ansisql`
|
Module :mod:`ansisql <migrate.changeset.ansisql>`
|
||||||
---------------------------------------
|
-------------------------------------------------
|
||||||
|
|
||||||
.. automodule:: migrate.changeset.ansisql
|
.. automodule:: migrate.changeset.ansisql
|
||||||
:members:
|
:members:
|
||||||
:synopsis: Standard SQL implementation for altering database schemas
|
:synopsis: Standard SQL implementation for altering database schemas
|
||||||
|
|
||||||
|
Module :mod:`databases <migrate.changeset.databases>`
|
||||||
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
.. automodule:: migrate.changeset.databases
|
||||||
|
:members:
|
||||||
|
:synopsis: Database specific changeset implementations
|
||||||
|
|
||||||
|
Module :mod:`mysql <migrate.changeset.databases.mysql>`
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. automodule:: migrate.changeset.databases.mysql
|
||||||
|
:members:
|
||||||
|
:synopsis: MySQL database specific changeset implementations
|
||||||
|
|
||||||
|
Module :mod:`oracle <migrate.changeset.databases.oracle>`
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. automodule:: migrate.changeset.databases.oracle
|
||||||
|
:members:
|
||||||
|
:synopsis: Oracle database specific changeset implementations
|
||||||
|
|
||||||
|
Module :mod:`postgres <migrate.changeset.databases.postgres>`
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. automodule:: migrate.changeset.databases.postgres
|
||||||
|
:members:
|
||||||
|
:synopsis: PostgreSQL database specific changeset implementations
|
||||||
|
|
||||||
|
Module :mod:`sqlite <migrate.changeset.databases.slite>`
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. automodule:: migrate.changeset.databases.sqlite
|
||||||
|
:members:
|
||||||
|
:synopsis: SQLite database specific changeset implementations
|
||||||
|
|
||||||
|
Module :mod:`visitor <migrate.changeset.databases.visitor>`
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
.. automodule:: migrate.changeset.databases.visitor
|
||||||
|
:members:
|
||||||
|
|
||||||
Module :mod:`migrate.versioning`
|
Module :mod:`migrate.versioning`
|
||||||
================================
|
================================
|
||||||
|
|
||||||
|
@ -1,3 +1,7 @@
|
|||||||
|
"""
|
||||||
|
This module contains database dialect specific changeset
|
||||||
|
implementations.
|
||||||
|
"""
|
||||||
__all__=[
|
__all__=[
|
||||||
'postgres',
|
'postgres',
|
||||||
'sqlite',
|
'sqlite',
|
||||||
|
@ -1,52 +1,74 @@
|
|||||||
from migrate.changeset import ansisql,exceptions
|
"""
|
||||||
|
MySQL database specific implementations of changeset classes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from migrate.changeset import ansisql, exceptions
|
||||||
from sqlalchemy.databases import mysql as sa_base
|
from sqlalchemy.databases import mysql as sa_base
|
||||||
#import sqlalchemy as sa
|
#import sqlalchemy as sa
|
||||||
|
|
||||||
MySQLSchemaGenerator = sa_base.MySQLSchemaGenerator
|
MySQLSchemaGenerator = sa_base.MySQLSchemaGenerator
|
||||||
|
|
||||||
class MySQLColumnGenerator(MySQLSchemaGenerator,ansisql.ANSIColumnGenerator):
|
|
||||||
|
class MySQLColumnGenerator(MySQLSchemaGenerator, ansisql.ANSIColumnGenerator):
|
||||||
|
|
||||||
def _do_quote_table_identifier(self, identifier):
|
def _do_quote_table_identifier(self, identifier):
|
||||||
return '%s'%identifier
|
return '%s'%identifier
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class MySQLColumnDropper(ansisql.ANSIColumnDropper):
|
class MySQLColumnDropper(ansisql.ANSIColumnDropper):
|
||||||
|
|
||||||
def _do_quote_table_identifier(self, identifier):
|
def _do_quote_table_identifier(self, identifier):
|
||||||
return '%s'%identifier
|
return '%s'%identifier
|
||||||
|
|
||||||
def _do_quote_column_identifier(self, identifier):
|
def _do_quote_column_identifier(self, identifier):
|
||||||
return '%s'%identifier
|
return '%s'%identifier
|
||||||
|
|
||||||
class MySQLSchemaChanger(MySQLSchemaGenerator,ansisql.ANSISchemaChanger):
|
|
||||||
def visit_column(self,delta):
|
class MySQLSchemaChanger(MySQLSchemaGenerator, ansisql.ANSISchemaChanger):
|
||||||
|
|
||||||
|
def visit_column(self, delta):
|
||||||
keys = delta.keys()
|
keys = delta.keys()
|
||||||
if 'type' in keys or 'nullable' in keys or 'name' in keys:
|
if 'type' in keys or 'nullable' in keys or 'name' in keys:
|
||||||
self._run_subvisit(delta,self._visit_column_change)
|
self._run_subvisit(delta, self._visit_column_change)
|
||||||
if 'server_default' in keys:
|
if 'server_default' in keys:
|
||||||
# Column name might have changed above
|
# Column name might have changed above
|
||||||
col_name = delta.get('name',delta.current_name)
|
col_name = delta.get('name', delta.current_name)
|
||||||
self._run_subvisit(delta,self._visit_column_default,col_name=col_name)
|
self._run_subvisit(delta, self._visit_column_default,
|
||||||
def _visit_column_change(self,table_name,col_name,delta):
|
col_name=col_name)
|
||||||
if not hasattr(delta,'result_column'):
|
|
||||||
# Mysql needs the whole column definition, not just a lone name/type
|
def _visit_column_change(self, table_name, col_name, delta):
|
||||||
|
if not hasattr(delta, 'result_column'):
|
||||||
|
# Mysql needs the whole column definition, not just a lone
|
||||||
|
# name/type
|
||||||
raise exceptions.NotSupportedError(
|
raise exceptions.NotSupportedError(
|
||||||
"A column object is required to do this")
|
"A column object is required to do this")
|
||||||
|
|
||||||
column = delta.result_column
|
column = delta.result_column
|
||||||
if not column.table: column.table = delta.table # needed by get_column_specification
|
# needed by get_column_specification
|
||||||
|
if not column.table:
|
||||||
|
column.table = delta.table
|
||||||
colspec = self.get_column_specification(column)
|
colspec = self.get_column_specification(column)
|
||||||
self.start_alter_table(table_name)
|
self.start_alter_table(table_name)
|
||||||
self.append("CHANGE COLUMN ")
|
self.append("CHANGE COLUMN ")
|
||||||
self.append(col_name)
|
self.append(col_name)
|
||||||
self.append(' ')
|
self.append(' ')
|
||||||
self.append(colspec)
|
self.append(colspec)
|
||||||
def visit_index(self,param):
|
|
||||||
|
def visit_index(self, param):
|
||||||
# If MySQL can do this, I can't find how
|
# If MySQL can do this, I can't find how
|
||||||
raise exceptions.NotSupportedError("MySQL cannot rename indexes")
|
raise exceptions.NotSupportedError("MySQL cannot rename indexes")
|
||||||
|
|
||||||
def _do_quote_table_identifier(self, identifier):
|
def _do_quote_table_identifier(self, identifier):
|
||||||
return '%s'%identifier
|
return '%s'%identifier
|
||||||
|
|
||||||
|
|
||||||
class MySQLConstraintGenerator(ansisql.ANSIConstraintGenerator):
|
class MySQLConstraintGenerator(ansisql.ANSIConstraintGenerator):
|
||||||
|
|
||||||
def _do_quote_table_identifier(self, identifier):
|
def _do_quote_table_identifier(self, identifier):
|
||||||
return '%s'%identifier
|
return '%s'%identifier
|
||||||
|
|
||||||
|
|
||||||
class MySQLConstraintDropper(ansisql.ANSIConstraintDropper):
|
class MySQLConstraintDropper(ansisql.ANSIConstraintDropper):
|
||||||
#def visit_constraint(self,constraint):
|
#def visit_constraint(self,constraint):
|
||||||
# if isinstance(constraint,sqlalchemy.schema.PrimaryKeyConstraint):
|
# if isinstance(constraint,sqlalchemy.schema.PrimaryKeyConstraint):
|
||||||
@ -54,12 +76,13 @@ class MySQLConstraintDropper(ansisql.ANSIConstraintDropper):
|
|||||||
# elif isinstance(constraint,sqlalchemy.schema.ForeignKeyConstraint):
|
# elif isinstance(constraint,sqlalchemy.schema.ForeignKeyConstraint):
|
||||||
# return self._visit_constraint_fk(constraint)
|
# return self._visit_constraint_fk(constraint)
|
||||||
# return super(MySQLConstraintDropper,self).visit_constraint(constraint)
|
# return super(MySQLConstraintDropper,self).visit_constraint(constraint)
|
||||||
def visit_migrate_primary_key_constraint(self,constraint):
|
|
||||||
|
def visit_migrate_primary_key_constraint(self, constraint):
|
||||||
self.start_alter_table(constraint)
|
self.start_alter_table(constraint)
|
||||||
self.append("DROP PRIMARY KEY")
|
self.append("DROP PRIMARY KEY")
|
||||||
self.execute()
|
self.execute()
|
||||||
|
|
||||||
def visit_migrate_foreign_key_constraint(self,constraint):
|
def visit_migrate_foreign_key_constraint(self, constraint):
|
||||||
self.start_alter_table(constraint)
|
self.start_alter_table(constraint)
|
||||||
self.append("DROP FOREIGN KEY ")
|
self.append("DROP FOREIGN KEY ")
|
||||||
self.append(constraint.name)
|
self.append(constraint.name)
|
||||||
@ -68,6 +91,7 @@ class MySQLConstraintDropper(ansisql.ANSIConstraintDropper):
|
|||||||
def _do_quote_table_identifier(self, identifier):
|
def _do_quote_table_identifier(self, identifier):
|
||||||
return '%s'%identifier
|
return '%s'%identifier
|
||||||
|
|
||||||
|
|
||||||
class MySQLDialect(ansisql.ANSIDialect):
|
class MySQLDialect(ansisql.ANSIDialect):
|
||||||
columngenerator = MySQLColumnGenerator
|
columngenerator = MySQLColumnGenerator
|
||||||
columndropper = MySQLColumnDropper
|
columndropper = MySQLColumnDropper
|
||||||
|
@ -1,54 +1,74 @@
|
|||||||
from migrate.changeset import ansisql,exceptions
|
"""
|
||||||
|
Oracle database specific implementations of changeset classes.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from migrate.changeset import ansisql, exceptions
|
||||||
from sqlalchemy.databases import oracle as sa_base
|
from sqlalchemy.databases import oracle as sa_base
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
|
|
||||||
OracleSchemaGenerator = sa_base.OracleSchemaGenerator
|
OracleSchemaGenerator = sa_base.OracleSchemaGenerator
|
||||||
|
|
||||||
class OracleColumnGenerator(OracleSchemaGenerator,ansisql.ANSIColumnGenerator):
|
|
||||||
|
class OracleColumnGenerator(OracleSchemaGenerator,
|
||||||
|
ansisql.ANSIColumnGenerator):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OracleColumnDropper(ansisql.ANSIColumnDropper):
|
class OracleColumnDropper(ansisql.ANSIColumnDropper):
|
||||||
pass
|
pass
|
||||||
class OracleSchemaChanger(OracleSchemaGenerator,ansisql.ANSISchemaChanger):
|
|
||||||
def get_column_specification(self,column,**kwargs):
|
|
||||||
|
class OracleSchemaChanger(OracleSchemaGenerator, ansisql.ANSISchemaChanger):
|
||||||
|
|
||||||
|
def get_column_specification(self, column, **kwargs):
|
||||||
# Ignore the NOT NULL generated
|
# Ignore the NOT NULL generated
|
||||||
override_nullable = kwargs.pop('override_nullable',None)
|
override_nullable = kwargs.pop('override_nullable', None)
|
||||||
if override_nullable:
|
if override_nullable:
|
||||||
orig = column.nullable
|
orig = column.nullable
|
||||||
column.nullable = True
|
column.nullable = True
|
||||||
ret=super(OracleSchemaChanger,self).get_column_specification(column,**kwargs)
|
ret = super(OracleSchemaChanger, self).get_column_specification(
|
||||||
|
column, **kwargs)
|
||||||
if override_nullable:
|
if override_nullable:
|
||||||
column.nullable = orig
|
column.nullable = orig
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
def visit_column(self,delta):
|
def visit_column(self, delta):
|
||||||
keys = delta.keys()
|
keys = delta.keys()
|
||||||
if 'type' in keys or 'nullable' in keys or 'default' in keys or 'server_default' in keys:
|
if 'type' in keys or 'nullable' in keys or 'default' in keys \
|
||||||
self._run_subvisit(delta,self._visit_column_change)
|
or 'server_default' in keys:
|
||||||
|
self._run_subvisit(delta, self._visit_column_change)
|
||||||
if 'name' in keys:
|
if 'name' in keys:
|
||||||
self._run_subvisit(delta,self._visit_column_name)
|
self._run_subvisit(delta, self._visit_column_name)
|
||||||
def _visit_column_change(self,table_name,col_name,delta):
|
|
||||||
if not hasattr(delta,'result_column'):
|
def _visit_column_change(self, table_name, col_name, delta):
|
||||||
# Oracle needs the whole column definition, not just a lone name/type
|
if not hasattr(delta, 'result_column'):
|
||||||
|
# Oracle needs the whole column definition, not just a
|
||||||
|
# lone name/type
|
||||||
raise exceptions.NotSupportedError(
|
raise exceptions.NotSupportedError(
|
||||||
"A column object is required to do this")
|
"A column object is required to do this")
|
||||||
|
|
||||||
column = delta.result_column
|
column = delta.result_column
|
||||||
# Oracle cannot drop a default once created, but it can set it to null.
|
# Oracle cannot drop a default once created, but it can set it
|
||||||
# We'll do that if default=None
|
# to null. We'll do that if default=None
|
||||||
# http://forums.oracle.com/forums/message.jspa?messageID=1273234#1273234
|
# http://forums.oracle.com/forums/message.jspa?\
|
||||||
dropdefault_hack = (column.server_default is None and 'server_default' in delta.keys())
|
# messageID=1273234#1273234
|
||||||
# Oracle apparently doesn't like it when we say "not null" if the
|
dropdefault_hack = (column.server_default is None \
|
||||||
# column's already not null. Fudge it, so we don't need a new function
|
and 'server_default' in delta.keys())
|
||||||
notnull_hack = ((not column.nullable) and ('nullable' not in delta.keys()))
|
# Oracle apparently doesn't like it when we say "not null" if
|
||||||
# We need to specify NULL if we're removing a NOT NULL constraint
|
# the column's already not null. Fudge it, so we don't need a
|
||||||
|
# new function
|
||||||
|
notnull_hack = ((not column.nullable) \
|
||||||
|
and ('nullable' not in delta.keys()))
|
||||||
|
# We need to specify NULL if we're removing a NOT NULL
|
||||||
|
# constraint
|
||||||
null_hack = (column.nullable and ('nullable' in delta.keys()))
|
null_hack = (column.nullable and ('nullable' in delta.keys()))
|
||||||
|
|
||||||
|
|
||||||
if dropdefault_hack:
|
if dropdefault_hack:
|
||||||
column.server_default = sa.PassiveDefault(sa.sql.null())
|
column.server_default = sa.PassiveDefault(sa.sql.null())
|
||||||
if notnull_hack:
|
if notnull_hack:
|
||||||
column.nullable = True
|
column.nullable = True
|
||||||
colspec=self.get_column_specification(column,override_nullable=null_hack)
|
colspec=self.get_column_specification(column,
|
||||||
|
override_nullable=null_hack)
|
||||||
if null_hack:
|
if null_hack:
|
||||||
colspec += ' NULL'
|
colspec += ' NULL'
|
||||||
if notnull_hack:
|
if notnull_hack:
|
||||||
@ -59,18 +79,28 @@ class OracleSchemaChanger(OracleSchemaGenerator,ansisql.ANSISchemaChanger):
|
|||||||
self.start_alter_table(table_name)
|
self.start_alter_table(table_name)
|
||||||
self.append("MODIFY ")
|
self.append("MODIFY ")
|
||||||
self.append(colspec)
|
self.append(colspec)
|
||||||
|
|
||||||
|
|
||||||
class OracleConstraintCommon(object):
|
class OracleConstraintCommon(object):
|
||||||
def get_constraint_name(self,cons):
|
|
||||||
|
def get_constraint_name(self, cons):
|
||||||
# Oracle constraints can't guess their name like other DBs
|
# Oracle constraints can't guess their name like other DBs
|
||||||
if not cons.name:
|
if not cons.name:
|
||||||
raise exceptions.NotSupportedError(
|
raise exceptions.NotSupportedError(
|
||||||
"Oracle constraint names must be explicitly stated")
|
"Oracle constraint names must be explicitly stated")
|
||||||
return cons.name
|
return cons.name
|
||||||
class OracleConstraintGenerator(OracleConstraintCommon,ansisql.ANSIConstraintGenerator):
|
|
||||||
|
|
||||||
|
class OracleConstraintGenerator(OracleConstraintCommon,
|
||||||
|
ansisql.ANSIConstraintGenerator):
|
||||||
pass
|
pass
|
||||||
class OracleConstraintDropper(OracleConstraintCommon,ansisql.ANSIConstraintDropper):
|
|
||||||
|
|
||||||
|
class OracleConstraintDropper(OracleConstraintCommon,
|
||||||
|
ansisql.ANSIConstraintDropper):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class OracleDialect(ansisql.ANSIDialect):
|
class OracleDialect(ansisql.ANSIDialect):
|
||||||
columngenerator = OracleColumnGenerator
|
columngenerator = OracleColumnGenerator
|
||||||
columndropper = OracleColumnDropper
|
columndropper = OracleColumnDropper
|
||||||
|
@ -1,44 +1,53 @@
|
|||||||
|
"""
|
||||||
|
`PostgreSQL`_ database specific implementations of changeset classes.
|
||||||
|
|
||||||
|
.. _`PostgreSQL`: http://www.postgresql.org/
|
||||||
|
"""
|
||||||
from migrate.changeset import ansisql
|
from migrate.changeset import ansisql
|
||||||
from sqlalchemy.databases import postgres as sa_base
|
from sqlalchemy.databases import postgres as sa_base
|
||||||
#import sqlalchemy as sa
|
#import sqlalchemy as sa
|
||||||
|
|
||||||
|
|
||||||
PGSchemaGenerator = sa_base.PGSchemaGenerator
|
PGSchemaGenerator = sa_base.PGSchemaGenerator
|
||||||
|
|
||||||
|
|
||||||
class PGSchemaGeneratorMixin(object):
|
class PGSchemaGeneratorMixin(object):
|
||||||
|
"""Common code used by the PostgreSQL specific classes."""
|
||||||
|
|
||||||
def _do_quote_table_identifier(self, identifier):
|
def _do_quote_table_identifier(self, identifier):
|
||||||
return identifier
|
return identifier
|
||||||
|
|
||||||
def _do_quote_column_identifier(self, identifier):
|
def _do_quote_column_identifier(self, identifier):
|
||||||
return '"%s"'%identifier
|
return '"%s"'%identifier
|
||||||
|
|
||||||
class PGColumnGenerator(PGSchemaGenerator,ansisql.ANSIColumnGenerator, PGSchemaGeneratorMixin):
|
|
||||||
def _do_quote_table_identifier(self, identifier):
|
class PGColumnGenerator(PGSchemaGenerator, ansisql.ANSIColumnGenerator,
|
||||||
return identifier
|
PGSchemaGeneratorMixin):
|
||||||
def _do_quote_column_identifier(self, identifier):
|
"""PostgreSQL column generator implementation."""
|
||||||
return '"%s"'%identifier
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PGColumnDropper(ansisql.ANSIColumnDropper, PGSchemaGeneratorMixin):
|
class PGColumnDropper(ansisql.ANSIColumnDropper, PGSchemaGeneratorMixin):
|
||||||
def _do_quote_table_identifier(self, identifier):
|
"""PostgreSQL column dropper implementation."""
|
||||||
return identifier
|
pass
|
||||||
def _do_quote_column_identifier(self, identifier):
|
|
||||||
return '"%s"'%identifier
|
|
||||||
|
|
||||||
class PGSchemaChanger(ansisql.ANSISchemaChanger, PGSchemaGeneratorMixin):
|
class PGSchemaChanger(ansisql.ANSISchemaChanger, PGSchemaGeneratorMixin):
|
||||||
def _do_quote_table_identifier(self, identifier):
|
"""PostgreSQL schema changer implementation."""
|
||||||
return identifier
|
pass
|
||||||
def _do_quote_column_identifier(self, identifier):
|
|
||||||
return '"%s"'%identifier
|
|
||||||
|
|
||||||
class PGConstraintGenerator(ansisql.ANSIConstraintGenerator, PGSchemaGeneratorMixin):
|
|
||||||
def _do_quote_table_identifier(self, identifier):
|
|
||||||
return identifier
|
|
||||||
def _do_quote_column_identifier(self, identifier):
|
|
||||||
return '"%s"'%identifier
|
|
||||||
|
|
||||||
class PGConstraintDropper(ansisql.ANSIConstraintDropper, PGSchemaGeneratorMixin):
|
class PGConstraintGenerator(ansisql.ANSIConstraintGenerator,
|
||||||
def _do_quote_table_identifier(self, identifier):
|
PGSchemaGeneratorMixin):
|
||||||
return identifier
|
"""PostgreSQL constraint generator implementation."""
|
||||||
def _do_quote_column_identifier(self, identifier):
|
pass
|
||||||
return '"%s"'%identifier
|
|
||||||
|
|
||||||
|
class PGConstraintDropper(ansisql.ANSIConstraintDropper,
|
||||||
|
PGSchemaGeneratorMixin):
|
||||||
|
"""PostgreSQL constaint dropper implementation."""
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
class PGDialect(ansisql.ANSIDialect):
|
class PGDialect(ansisql.ANSIDialect):
|
||||||
columngenerator = PGColumnGenerator
|
columngenerator = PGColumnGenerator
|
||||||
|
@ -1,11 +1,18 @@
|
|||||||
from migrate.changeset import ansisql,constraint,exceptions
|
"""
|
||||||
|
`SQLite`_ database specific implementations of changeset classes.
|
||||||
|
|
||||||
|
.. _`SQLite`: http://www.sqlite.org/
|
||||||
|
"""
|
||||||
|
from migrate.changeset import ansisql, constraint, exceptions
|
||||||
from sqlalchemy.databases import sqlite as sa_base
|
from sqlalchemy.databases import sqlite as sa_base
|
||||||
from sqlalchemy import Table, MetaData
|
from sqlalchemy import Table, MetaData
|
||||||
#import sqlalchemy as sa
|
#import sqlalchemy as sa
|
||||||
|
|
||||||
SQLiteSchemaGenerator = sa_base.SQLiteSchemaGenerator
|
SQLiteSchemaGenerator = sa_base.SQLiteSchemaGenerator
|
||||||
|
|
||||||
|
|
||||||
class SQLiteHelper(object):
|
class SQLiteHelper(object):
|
||||||
|
|
||||||
def visit_column(self, param):
|
def visit_column(self, param):
|
||||||
try:
|
try:
|
||||||
table = self._to_table(param.table)
|
table = self._to_table(param.table)
|
||||||
@ -24,50 +31,61 @@ class SQLiteHelper(object):
|
|||||||
self.append('DROP TABLE migration_tmp')
|
self.append('DROP TABLE migration_tmp')
|
||||||
self.execute()
|
self.execute()
|
||||||
|
|
||||||
class SQLiteColumnGenerator(SQLiteSchemaGenerator,ansisql.ANSIColumnGenerator):
|
|
||||||
|
class SQLiteColumnGenerator(SQLiteSchemaGenerator,
|
||||||
|
ansisql.ANSIColumnGenerator):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
|
||||||
class SQLiteColumnDropper(SQLiteHelper, ansisql.ANSIColumnDropper):
|
class SQLiteColumnDropper(SQLiteHelper, ansisql.ANSIColumnDropper):
|
||||||
def _modify_table(self,table, column):
|
|
||||||
|
def _modify_table(self, table, column):
|
||||||
del table.columns[column.name]
|
del table.columns[column.name]
|
||||||
columns = ','.join([c.name for c in table.columns])
|
return 'INSERT INTO %(table_name)s SELECT %s from migration_tmp' % \
|
||||||
return 'INSERT INTO %(table_name)s SELECT ' + columns + ' from migration_tmp'
|
','.join([c.name for c in table.columns])
|
||||||
|
|
||||||
|
|
||||||
class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger):
|
class SQLiteSchemaChanger(SQLiteHelper, ansisql.ANSISchemaChanger):
|
||||||
def _not_supported(self,op):
|
|
||||||
|
def _not_supported(self, op):
|
||||||
raise exceptions.NotSupportedError("SQLite does not support "
|
raise exceptions.NotSupportedError("SQLite does not support "
|
||||||
"%s; see http://www.sqlite.org/lang_altertable.html"%op)
|
"%s; see http://www.sqlite.org/lang_altertable.html"%op)
|
||||||
|
|
||||||
def _modify_table(self, table, delta):
|
def _modify_table(self, table, delta):
|
||||||
column = table.columns[delta.current_name]
|
column = table.columns[delta.current_name]
|
||||||
for k,v in delta.items():
|
for k, v in delta.items():
|
||||||
setattr(column, k, v)
|
setattr(column, k, v)
|
||||||
return 'INSERT INTO %(table_name)s SELECT * from migration_tmp'
|
return 'INSERT INTO %(table_name)s SELECT * from migration_tmp'
|
||||||
|
|
||||||
def visit_index(self,param):
|
def visit_index(self, param):
|
||||||
self._not_supported('ALTER INDEX')
|
self._not_supported('ALTER INDEX')
|
||||||
|
|
||||||
def _do_quote_column_identifier(self, identifier):
|
def _do_quote_column_identifier(self, identifier):
|
||||||
return '"%s"'%identifier
|
return '"%s"'%identifier
|
||||||
|
|
||||||
|
|
||||||
class SQLiteConstraintGenerator(ansisql.ANSIConstraintGenerator):
|
class SQLiteConstraintGenerator(ansisql.ANSIConstraintGenerator):
|
||||||
def visit_migrate_primary_key_constraint(self,constraint):
|
|
||||||
|
def visit_migrate_primary_key_constraint(self, constraint):
|
||||||
tmpl = "CREATE UNIQUE INDEX %s ON %s ( %s )"
|
tmpl = "CREATE UNIQUE INDEX %s ON %s ( %s )"
|
||||||
cols = ','.join([c.name for c in constraint.columns])
|
cols = ','.join([c.name for c in constraint.columns])
|
||||||
tname = constraint.table.name
|
tname = constraint.table.name
|
||||||
name = constraint.name
|
name = constraint.name
|
||||||
msg = tmpl%(name,tname,cols)
|
msg = tmpl % (name, tname, cols)
|
||||||
self.append(msg)
|
self.append(msg)
|
||||||
self.execute()
|
self.execute()
|
||||||
|
|
||||||
|
|
||||||
class SQLiteConstraintDropper(ansisql.ANSIColumnDropper):
|
class SQLiteConstraintDropper(ansisql.ANSIColumnDropper):
|
||||||
def visit_migrate_primary_key_constraint(self,constraint):
|
|
||||||
|
def visit_migrate_primary_key_constraint(self, constraint):
|
||||||
tmpl = "DROP INDEX %s "
|
tmpl = "DROP INDEX %s "
|
||||||
name = constraint.name
|
name = constraint.name
|
||||||
msg = tmpl%(name)
|
msg = tmpl % (name)
|
||||||
self.append(msg)
|
self.append(msg)
|
||||||
self.execute()
|
self.execute()
|
||||||
|
|
||||||
|
|
||||||
class SQLiteDialect(ansisql.ANSIDialect):
|
class SQLiteDialect(ansisql.ANSIDialect):
|
||||||
columngenerator = SQLiteColumnGenerator
|
columngenerator = SQLiteColumnGenerator
|
||||||
columndropper = SQLiteColumnDropper
|
columndropper = SQLiteColumnDropper
|
||||||
|
@ -1,20 +1,34 @@
|
|||||||
|
"""
|
||||||
|
Module for visitor class mapping.
|
||||||
|
"""
|
||||||
import sqlalchemy as sa
|
import sqlalchemy as sa
|
||||||
from migrate.changeset.databases import sqlite,postgres,mysql,oracle
|
from migrate.changeset.databases import sqlite, postgres, mysql, oracle
|
||||||
from migrate.changeset import ansisql
|
from migrate.changeset import ansisql
|
||||||
|
|
||||||
# Map SA dialects to the corresponding Migrate extensions
|
# Map SA dialects to the corresponding Migrate extensions
|
||||||
dialects = {
|
dialects = {
|
||||||
sa.engine.default.DefaultDialect : ansisql.ANSIDialect,
|
sa.engine.default.DefaultDialect: ansisql.ANSIDialect,
|
||||||
sa.databases.sqlite.SQLiteDialect : sqlite.SQLiteDialect,
|
sa.databases.sqlite.SQLiteDialect: sqlite.SQLiteDialect,
|
||||||
sa.databases.postgres.PGDialect : postgres.PGDialect,
|
sa.databases.postgres.PGDialect: postgres.PGDialect,
|
||||||
sa.databases.mysql.MySQLDialect : mysql.MySQLDialect,
|
sa.databases.mysql.MySQLDialect: mysql.MySQLDialect,
|
||||||
sa.databases.oracle.OracleDialect : oracle.OracleDialect,
|
sa.databases.oracle.OracleDialect: oracle.OracleDialect,
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_engine_visitor(engine,name):
|
|
||||||
return get_dialect_visitor(engine.dialect,name)
|
|
||||||
|
|
||||||
def get_dialect_visitor(sa_dialect,name):
|
def get_engine_visitor(engine, name):
|
||||||
|
"""
|
||||||
|
Get the visitor implementation for the given database engine.
|
||||||
|
"""
|
||||||
|
return get_dialect_visitor(engine.dialect, name)
|
||||||
|
|
||||||
|
|
||||||
|
def get_dialect_visitor(sa_dialect, name):
|
||||||
|
"""
|
||||||
|
Get the visitor implementation for the given dialect.
|
||||||
|
|
||||||
|
Finds the visitor implementation based on the dialect class and
|
||||||
|
returns and instance initialized with the given name.
|
||||||
|
"""
|
||||||
sa_dialect_cls = sa_dialect.__class__
|
sa_dialect_cls = sa_dialect.__class__
|
||||||
migrate_dialect_cls = dialects[sa_dialect_cls]
|
migrate_dialect_cls = dialects[sa_dialect_cls]
|
||||||
return migrate_dialect_cls.visitor(name)
|
return migrate_dialect_cls.visitor(name)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user