add Linux_i686

This commit is contained in:
j 2014-05-17 18:11:40 +00:00 committed by Ubuntu
commit 95cd9b11f2
1644 changed files with 564260 additions and 0 deletions

View file

@ -0,0 +1,2 @@
from . import postgresql, mysql, sqlite, mssql, oracle
from .impl import DefaultImpl

View file

@ -0,0 +1,161 @@
import functools
from sqlalchemy.ext.compiler import compiles
from sqlalchemy.schema import DDLElement, Column
from sqlalchemy import Integer
from sqlalchemy import types as sqltypes
class AlterTable(DDLElement):
"""Represent an ALTER TABLE statement.
Only the string name and optional schema name of the table
is required, not a full Table object.
"""
def __init__(self, table_name, schema=None):
self.table_name = table_name
self.schema = schema
class RenameTable(AlterTable):
def __init__(self, old_table_name, new_table_name, schema=None):
super(RenameTable, self).__init__(old_table_name, schema=schema)
self.new_table_name = new_table_name
class AlterColumn(AlterTable):
def __init__(self, name, column_name, schema=None,
existing_type=None,
existing_nullable=None,
existing_server_default=None):
super(AlterColumn, self).__init__(name, schema=schema)
self.column_name = column_name
self.existing_type=sqltypes.to_instance(existing_type) \
if existing_type is not None else None
self.existing_nullable=existing_nullable
self.existing_server_default=existing_server_default
class ColumnNullable(AlterColumn):
def __init__(self, name, column_name, nullable, **kw):
super(ColumnNullable, self).__init__(name, column_name,
**kw)
self.nullable = nullable
class ColumnType(AlterColumn):
def __init__(self, name, column_name, type_, **kw):
super(ColumnType, self).__init__(name, column_name,
**kw)
self.type_ = sqltypes.to_instance(type_)
class ColumnName(AlterColumn):
def __init__(self, name, column_name, newname, **kw):
super(ColumnName, self).__init__(name, column_name, **kw)
self.newname = newname
class ColumnDefault(AlterColumn):
def __init__(self, name, column_name, default, **kw):
super(ColumnDefault, self).__init__(name, column_name, **kw)
self.default = default
class AddColumn(AlterTable):
def __init__(self, name, column, schema=None):
super(AddColumn, self).__init__(name, schema=schema)
self.column = column
class DropColumn(AlterTable):
def __init__(self, name, column, schema=None):
super(DropColumn, self).__init__(name, schema=schema)
self.column = column
@compiles(RenameTable)
def visit_rename_table(element, compiler, **kw):
return "%s RENAME TO %s" % (
alter_table(compiler, element.table_name, element.schema),
format_table_name(compiler, element.new_table_name, element.schema)
)
@compiles(AddColumn)
def visit_add_column(element, compiler, **kw):
return "%s %s" % (
alter_table(compiler, element.table_name, element.schema),
add_column(compiler, element.column, **kw)
)
@compiles(DropColumn)
def visit_drop_column(element, compiler, **kw):
return "%s %s" % (
alter_table(compiler, element.table_name, element.schema),
drop_column(compiler, element.column.name, **kw)
)
@compiles(ColumnNullable)
def visit_column_nullable(element, compiler, **kw):
return "%s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
"DROP NOT NULL" if element.nullable else "SET NOT NULL"
)
@compiles(ColumnType)
def visit_column_type(element, compiler, **kw):
return "%s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
"TYPE %s" % format_type(compiler, element.type_)
)
@compiles(ColumnName)
def visit_column_name(element, compiler, **kw):
return "%s RENAME %s TO %s" % (
alter_table(compiler, element.table_name, element.schema),
format_column_name(compiler, element.column_name),
format_column_name(compiler, element.newname)
)
@compiles(ColumnDefault)
def visit_column_default(element, compiler, **kw):
return "%s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
"SET DEFAULT %s" %
format_server_default(compiler, element.default)
if element.default is not None
else "DROP DEFAULT"
)
def quote_dotted(name, quote):
"""quote the elements of a dotted name"""
result = '.'.join([quote(x) for x in name.split('.')])
return result
def format_table_name(compiler, name, schema):
quote = functools.partial(compiler.preparer.quote, force=None)
if schema:
return quote_dotted(schema, quote) + "." + quote(name)
else:
return quote(name)
def format_column_name(compiler, name):
return compiler.preparer.quote(name, None)
def format_server_default(compiler, default):
return compiler.get_column_default_string(
Column("x", Integer, server_default=default)
)
def format_type(compiler, type_):
return compiler.dialect.type_compiler.process(type_)
def alter_table(compiler, name, schema):
return "ALTER TABLE %s" % format_table_name(compiler, name, schema)
def drop_column(compiler, name):
return 'DROP COLUMN %s' % format_column_name(compiler, name)
def alter_column(compiler, name):
return 'ALTER COLUMN %s' % format_column_name(compiler, name)
def add_column(compiler, column, **kw):
return "ADD COLUMN %s" % compiler.get_column_specification(column, **kw)

View file

@ -0,0 +1,279 @@
from sqlalchemy.sql.expression import _BindParamClause
from sqlalchemy.ext.compiler import compiles
from sqlalchemy import schema, text
from sqlalchemy import types as sqltypes
from ..compat import string_types, text_type, with_metaclass
from .. import util
from . import base
class ImplMeta(type):
def __init__(cls, classname, bases, dict_):
newtype = type.__init__(cls, classname, bases, dict_)
if '__dialect__' in dict_:
_impls[dict_['__dialect__']] = cls
return newtype
_impls = {}
class DefaultImpl(with_metaclass(ImplMeta)):
"""Provide the entrypoint for major migration operations,
including database-specific behavioral variances.
While individual SQL/DDL constructs already provide
for database-specific implementations, variances here
allow for entirely different sequences of operations
to take place for a particular migration, such as
SQL Server's special 'IDENTITY INSERT' step for
bulk inserts.
"""
__dialect__ = 'default'
transactional_ddl = False
command_terminator = ";"
def __init__(self, dialect, connection, as_sql,
transactional_ddl, output_buffer,
context_opts):
self.dialect = dialect
self.connection = connection
self.as_sql = as_sql
self.output_buffer = output_buffer
self.memo = {}
self.context_opts = context_opts
if transactional_ddl is not None:
self.transactional_ddl = transactional_ddl
@classmethod
def get_by_dialect(cls, dialect):
return _impls[dialect.name]
def static_output(self, text):
self.output_buffer.write(text_type(text + "\n\n"))
self.output_buffer.flush()
@property
def bind(self):
return self.connection
def _exec(self, construct, execution_options=None,
multiparams=(),
params=util.immutabledict()):
if isinstance(construct, string_types):
construct = text(construct)
if self.as_sql:
if multiparams or params:
# TODO: coverage
raise Exception("Execution arguments not allowed with as_sql")
self.static_output(text_type(
construct.compile(dialect=self.dialect)
).replace("\t", " ").strip() + self.command_terminator)
else:
conn = self.connection
if execution_options:
conn = conn.execution_options(**execution_options)
conn.execute(construct, *multiparams, **params)
def execute(self, sql, execution_options=None):
self._exec(sql, execution_options)
def alter_column(self, table_name, column_name,
nullable=None,
server_default=False,
name=None,
type_=None,
schema=None,
autoincrement=None,
existing_type=None,
existing_server_default=None,
existing_nullable=None,
existing_autoincrement=None
):
if autoincrement is not None or existing_autoincrement is not None:
util.warn("nautoincrement and existing_autoincrement only make sense for MySQL")
if nullable is not None:
self._exec(base.ColumnNullable(table_name, column_name,
nullable, schema=schema,
existing_type=existing_type,
existing_server_default=existing_server_default,
existing_nullable=existing_nullable,
))
if server_default is not False:
self._exec(base.ColumnDefault(
table_name, column_name, server_default,
schema=schema,
existing_type=existing_type,
existing_server_default=existing_server_default,
existing_nullable=existing_nullable,
))
if type_ is not None:
self._exec(base.ColumnType(
table_name, column_name, type_, schema=schema,
existing_type=existing_type,
existing_server_default=existing_server_default,
existing_nullable=existing_nullable,
))
# do the new name last ;)
if name is not None:
self._exec(base.ColumnName(
table_name, column_name, name, schema=schema,
existing_type=existing_type,
existing_server_default=existing_server_default,
existing_nullable=existing_nullable,
))
def add_column(self, table_name, column, schema=None):
self._exec(base.AddColumn(table_name, column, schema=schema))
def drop_column(self, table_name, column, schema=None, **kw):
self._exec(base.DropColumn(table_name, column, schema=schema))
def add_constraint(self, const):
if const._create_rule is None or \
const._create_rule(self):
self._exec(schema.AddConstraint(const))
def drop_constraint(self, const):
self._exec(schema.DropConstraint(const))
def rename_table(self, old_table_name, new_table_name, schema=None):
self._exec(base.RenameTable(old_table_name,
new_table_name, schema=schema))
def create_table(self, table):
if util.sqla_07:
table.dispatch.before_create(table, self.connection,
checkfirst=False,
_ddl_runner=self)
self._exec(schema.CreateTable(table))
if util.sqla_07:
table.dispatch.after_create(table, self.connection,
checkfirst=False,
_ddl_runner=self)
for index in table.indexes:
self._exec(schema.CreateIndex(index))
def drop_table(self, table):
self._exec(schema.DropTable(table))
def create_index(self, index):
self._exec(schema.CreateIndex(index))
def drop_index(self, index):
self._exec(schema.DropIndex(index))
def bulk_insert(self, table, rows, multiinsert=True):
if not isinstance(rows, list):
raise TypeError("List expected")
elif rows and not isinstance(rows[0], dict):
raise TypeError("List of dictionaries expected")
if self.as_sql:
for row in rows:
self._exec(table.insert(inline=True).values(**dict(
(k,
_literal_bindparam(k, v, type_=table.c[k].type)
if not isinstance(v, _literal_bindparam) else v)
for k, v in row.items()
)))
else:
# work around http://www.sqlalchemy.org/trac/ticket/2461
if not hasattr(table, '_autoincrement_column'):
table._autoincrement_column = None
if rows:
if multiinsert:
self._exec(table.insert(inline=True), multiparams=rows)
else:
for row in rows:
self._exec(table.insert(inline=True).values(**row))
def compare_type(self, inspector_column, metadata_column):
conn_type = inspector_column.type
metadata_type = metadata_column.type
metadata_impl = metadata_type.dialect_impl(self.dialect)
# work around SQLAlchemy bug "stale value for type affinity"
# fixed in 0.7.4
metadata_impl.__dict__.pop('_type_affinity', None)
if conn_type._compare_type_affinity(
metadata_impl
):
comparator = _type_comparators.get(conn_type._type_affinity, None)
return comparator and comparator(metadata_type, conn_type)
else:
return True
def compare_server_default(self, inspector_column,
metadata_column,
rendered_metadata_default,
rendered_inspector_default):
return rendered_inspector_default != rendered_metadata_default
def correct_for_autogen_constraints(self, conn_uniques, conn_indexes,
metadata_unique_constraints,
metadata_indexes):
pass
def start_migrations(self):
"""A hook called when :meth:`.EnvironmentContext.run_migrations`
is called.
Implementations can set up per-migration-run state here.
"""
def emit_begin(self):
"""Emit the string ``BEGIN``, or the backend-specific
equivalent, on the current connection context.
This is used in offline mode and typically
via :meth:`.EnvironmentContext.begin_transaction`.
"""
self.static_output("BEGIN" + self.command_terminator)
def emit_commit(self):
"""Emit the string ``COMMIT``, or the backend-specific
equivalent, on the current connection context.
This is used in offline mode and typically
via :meth:`.EnvironmentContext.begin_transaction`.
"""
self.static_output("COMMIT" + self.command_terminator)
class _literal_bindparam(_BindParamClause):
pass
@compiles(_literal_bindparam)
def _render_literal_bindparam(element, compiler, **kw):
return compiler.render_literal_bindparam(element, **kw)
def _string_compare(t1, t2):
return \
t1.length is not None and \
t1.length != t2.length
def _numeric_compare(t1, t2):
return \
(
t1.precision is not None and \
t1.precision != t2.precision
) or \
(
t1.scale is not None and \
t1.scale != t2.scale
)
_type_comparators = {
sqltypes.String:_string_compare,
sqltypes.Numeric:_numeric_compare
}

View file

@ -0,0 +1,217 @@
from sqlalchemy.ext.compiler import compiles
from .. import util
from .impl import DefaultImpl
from .base import alter_table, AddColumn, ColumnName, \
format_table_name, format_column_name, ColumnNullable, alter_column,\
format_server_default,ColumnDefault, format_type, ColumnType
from sqlalchemy.sql.expression import ClauseElement, Executable
class MSSQLImpl(DefaultImpl):
__dialect__ = 'mssql'
transactional_ddl = True
batch_separator = "GO"
def __init__(self, *arg, **kw):
super(MSSQLImpl, self).__init__(*arg, **kw)
self.batch_separator = self.context_opts.get(
"mssql_batch_separator",
self.batch_separator)
def _exec(self, construct, *args, **kw):
super(MSSQLImpl, self)._exec(construct, *args, **kw)
if self.as_sql and self.batch_separator:
self.static_output(self.batch_separator)
def emit_begin(self):
self.static_output("BEGIN TRANSACTION" + self.command_terminator)
def emit_commit(self):
super(MSSQLImpl, self).emit_commit()
if self.as_sql and self.batch_separator:
self.static_output(self.batch_separator)
def alter_column(self, table_name, column_name,
nullable=None,
server_default=False,
name=None,
type_=None,
schema=None,
autoincrement=None,
existing_type=None,
existing_server_default=None,
existing_nullable=None,
existing_autoincrement=None
):
if nullable is not None and existing_type is None:
if type_ is not None:
existing_type = type_
# the NULL/NOT NULL alter will handle
# the type alteration
type_ = None
else:
raise util.CommandError(
"MS-SQL ALTER COLUMN operations "
"with NULL or NOT NULL require the "
"existing_type or a new type_ be passed.")
super(MSSQLImpl, self).alter_column(
table_name, column_name,
nullable=nullable,
type_=type_,
schema=schema,
autoincrement=autoincrement,
existing_type=existing_type,
existing_nullable=existing_nullable,
existing_autoincrement=existing_autoincrement
)
if server_default is not False:
if existing_server_default is not False or \
server_default is None:
self._exec(
_ExecDropConstraint(
table_name, column_name,
'sys.default_constraints')
)
if server_default is not None:
super(MSSQLImpl, self).alter_column(
table_name, column_name,
schema=schema,
server_default=server_default)
if name is not None:
super(MSSQLImpl, self).alter_column(
table_name, column_name,
schema=schema,
name=name)
def bulk_insert(self, table, rows, **kw):
if self.as_sql:
self._exec(
"SET IDENTITY_INSERT %s ON" %
self.dialect.identifier_preparer.format_table(table)
)
super(MSSQLImpl, self).bulk_insert(table, rows, **kw)
self._exec(
"SET IDENTITY_INSERT %s OFF" %
self.dialect.identifier_preparer.format_table(table)
)
else:
super(MSSQLImpl, self).bulk_insert(table, rows, **kw)
def drop_column(self, table_name, column, **kw):
drop_default = kw.pop('mssql_drop_default', False)
if drop_default:
self._exec(
_ExecDropConstraint(
table_name, column,
'sys.default_constraints')
)
drop_check = kw.pop('mssql_drop_check', False)
if drop_check:
self._exec(
_ExecDropConstraint(
table_name, column,
'sys.check_constraints')
)
drop_fks = kw.pop('mssql_drop_foreign_key', False)
if drop_fks:
self._exec(
_ExecDropFKConstraint(table_name, column)
)
super(MSSQLImpl, self).drop_column(table_name, column)
class _ExecDropConstraint(Executable, ClauseElement):
def __init__(self, tname, colname, type_):
self.tname = tname
self.colname = colname
self.type_ = type_
class _ExecDropFKConstraint(Executable, ClauseElement):
def __init__(self, tname, colname):
self.tname = tname
self.colname = colname
@compiles(_ExecDropConstraint, 'mssql')
def _exec_drop_col_constraint(element, compiler, **kw):
tname, colname, type_ = element.tname, element.colname, element.type_
# from http://www.mssqltips.com/sqlservertip/1425/working-with-default-constraints-in-sql-server/
# TODO: needs table formatting, etc.
return """declare @const_name varchar(256)
select @const_name = [name] from %(type)s
where parent_object_id = object_id('%(tname)s')
and col_name(parent_object_id, parent_column_id) = '%(colname)s'
exec('alter table %(tname_quoted)s drop constraint ' + @const_name)""" % {
'type': type_,
'tname': tname,
'colname': colname,
'tname_quoted': format_table_name(compiler, tname, None),
}
@compiles(_ExecDropFKConstraint, 'mssql')
def _exec_drop_col_fk_constraint(element, compiler, **kw):
tname, colname = element.tname, element.colname
return """declare @const_name varchar(256)
select @const_name = [name] from
sys.foreign_keys fk join sys.foreign_key_columns fkc
on fk.object_id=fkc.constraint_object_id
where fkc.parent_object_id = object_id('%(tname)s')
and col_name(fkc.parent_object_id, fkc.parent_column_id) = '%(colname)s'
exec('alter table %(tname_quoted)s drop constraint ' + @const_name)""" % {
'tname': tname,
'colname': colname,
'tname_quoted': format_table_name(compiler, tname, None),
}
@compiles(AddColumn, 'mssql')
def visit_add_column(element, compiler, **kw):
return "%s %s" % (
alter_table(compiler, element.table_name, element.schema),
mssql_add_column(compiler, element.column, **kw)
)
def mssql_add_column(compiler, column, **kw):
return "ADD %s" % compiler.get_column_specification(column, **kw)
@compiles(ColumnNullable, 'mssql')
def visit_column_nullable(element, compiler, **kw):
return "%s %s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
format_type(compiler, element.existing_type),
"NULL" if element.nullable else "NOT NULL"
)
@compiles(ColumnDefault, 'mssql')
def visit_column_default(element, compiler, **kw):
# TODO: there can also be a named constraint
# with ADD CONSTRAINT here
return "%s ADD DEFAULT %s FOR %s" % (
alter_table(compiler, element.table_name, element.schema),
format_server_default(compiler, element.default),
format_column_name(compiler, element.column_name)
)
@compiles(ColumnName, 'mssql')
def visit_rename_column(element, compiler, **kw):
return "EXEC sp_rename '%s.%s', %s, 'COLUMN'" % (
format_table_name(compiler, element.table_name, element.schema),
format_column_name(compiler, element.column_name),
format_column_name(compiler, element.newname)
)
@compiles(ColumnType, 'mssql')
def visit_column_type(element, compiler, **kw):
return "%s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
format_type(compiler, element.type_)
)

View file

@ -0,0 +1,212 @@
from sqlalchemy.ext.compiler import compiles
from sqlalchemy import types as sqltypes
from sqlalchemy import schema
from ..compat import string_types
from .. import util
from .impl import DefaultImpl
from .base import ColumnNullable, ColumnName, ColumnDefault, \
ColumnType, AlterColumn, format_column_name, \
format_server_default
from .base import alter_table
class MySQLImpl(DefaultImpl):
__dialect__ = 'mysql'
transactional_ddl = False
def alter_column(self, table_name, column_name,
nullable=None,
server_default=False,
name=None,
type_=None,
schema=None,
autoincrement=None,
existing_type=None,
existing_server_default=None,
existing_nullable=None,
existing_autoincrement=None
):
if name is not None:
self._exec(
MySQLChangeColumn(
table_name, column_name,
schema=schema,
newname=name,
nullable=nullable if nullable is not None else
existing_nullable
if existing_nullable is not None
else True,
type_=type_ if type_ is not None else existing_type,
default=server_default if server_default is not False
else existing_server_default,
autoincrement=autoincrement if autoincrement is not None
else existing_autoincrement
)
)
elif nullable is not None or \
type_ is not None or \
autoincrement is not None:
self._exec(
MySQLModifyColumn(
table_name, column_name,
schema=schema,
newname=name if name is not None else column_name,
nullable=nullable if nullable is not None else
existing_nullable
if existing_nullable is not None
else True,
type_=type_ if type_ is not None else existing_type,
default=server_default if server_default is not False
else existing_server_default,
autoincrement=autoincrement if autoincrement is not None
else existing_autoincrement
)
)
elif server_default is not False:
self._exec(
MySQLAlterDefault(
table_name, column_name, server_default,
schema=schema,
)
)
def correct_for_autogen_constraints(self, conn_unique_constraints,
conn_indexes,
metadata_unique_constraints,
metadata_indexes):
removed = set()
for idx in list(conn_indexes):
# MySQL puts implicit indexes on FK columns, even if
# composite and even if MyISAM, so can't check this too easily
if idx.name == idx.columns.keys()[0]:
conn_indexes.remove(idx)
removed.add(idx.name)
# then remove indexes from the "metadata_indexes"
# that we've removed from reflected, otherwise they come out
# as adds (see #202)
for idx in list(metadata_indexes):
if idx.name in removed:
metadata_indexes.remove(idx)
class MySQLAlterDefault(AlterColumn):
def __init__(self, name, column_name, default, schema=None):
super(AlterColumn, self).__init__(name, schema=schema)
self.column_name = column_name
self.default = default
class MySQLChangeColumn(AlterColumn):
def __init__(self, name, column_name, schema=None,
newname=None,
type_=None,
nullable=None,
default=False,
autoincrement=None):
super(AlterColumn, self).__init__(name, schema=schema)
self.column_name = column_name
self.nullable = nullable
self.newname = newname
self.default = default
self.autoincrement = autoincrement
if type_ is None:
raise util.CommandError(
"All MySQL CHANGE/MODIFY COLUMN operations "
"require the existing type."
)
self.type_ = sqltypes.to_instance(type_)
class MySQLModifyColumn(MySQLChangeColumn):
pass
@compiles(ColumnNullable, 'mysql')
@compiles(ColumnName, 'mysql')
@compiles(ColumnDefault, 'mysql')
@compiles(ColumnType, 'mysql')
def _mysql_doesnt_support_individual(element, compiler, **kw):
raise NotImplementedError(
"Individual alter column constructs not supported by MySQL"
)
@compiles(MySQLAlterDefault, "mysql")
def _mysql_alter_default(element, compiler, **kw):
return "%s ALTER COLUMN %s %s" % (
alter_table(compiler, element.table_name, element.schema),
format_column_name(compiler, element.column_name),
"SET DEFAULT %s" % format_server_default(compiler, element.default)
if element.default is not None
else "DROP DEFAULT"
)
@compiles(MySQLModifyColumn, "mysql")
def _mysql_modify_column(element, compiler, **kw):
return "%s MODIFY %s %s" % (
alter_table(compiler, element.table_name, element.schema),
format_column_name(compiler, element.column_name),
_mysql_colspec(
compiler,
nullable=element.nullable,
server_default=element.default,
type_=element.type_,
autoincrement=element.autoincrement
),
)
@compiles(MySQLChangeColumn, "mysql")
def _mysql_change_column(element, compiler, **kw):
return "%s CHANGE %s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
format_column_name(compiler, element.column_name),
format_column_name(compiler, element.newname),
_mysql_colspec(
compiler,
nullable=element.nullable,
server_default=element.default,
type_=element.type_,
autoincrement=element.autoincrement
),
)
def _render_value(compiler, expr):
if isinstance(expr, string_types):
return "'%s'" % expr
else:
return compiler.sql_compiler.process(expr)
def _mysql_colspec(compiler, nullable, server_default, type_,
autoincrement):
spec = "%s %s" % (
compiler.dialect.type_compiler.process(type_),
"NULL" if nullable else "NOT NULL"
)
if autoincrement:
spec += " AUTO_INCREMENT"
if server_default is not False and server_default is not None:
spec += " DEFAULT %s" % _render_value(compiler, server_default)
return spec
@compiles(schema.DropConstraint, "mysql")
def _mysql_drop_constraint(element, compiler, **kw):
"""Redefine SQLAlchemy's drop constraint to
raise errors for invalid constraint type."""
constraint = element.element
if isinstance(constraint, (schema.ForeignKeyConstraint,
schema.PrimaryKeyConstraint,
schema.UniqueConstraint)
):
return compiler.visit_drop_constraint(element, **kw)
elif isinstance(constraint, schema.CheckConstraint):
raise NotImplementedError(
"MySQL does not support CHECK constraints.")
else:
raise NotImplementedError(
"No generic 'DROP CONSTRAINT' in MySQL - "
"please specify constraint type")

View file

@ -0,0 +1,77 @@
from sqlalchemy.ext.compiler import compiles
from .impl import DefaultImpl
from .base import alter_table, AddColumn, ColumnName, \
format_column_name, ColumnNullable, \
format_server_default,ColumnDefault, format_type, ColumnType
class OracleImpl(DefaultImpl):
__dialect__ = 'oracle'
transactional_ddl = True
batch_separator = "/"
command_terminator = ""
def __init__(self, *arg, **kw):
super(OracleImpl, self).__init__(*arg, **kw)
self.batch_separator = self.context_opts.get(
"oracle_batch_separator",
self.batch_separator)
def _exec(self, construct, *args, **kw):
super(OracleImpl, self)._exec(construct, *args, **kw)
if self.as_sql and self.batch_separator:
self.static_output(self.batch_separator)
def emit_begin(self):
self._exec("SET TRANSACTION READ WRITE")
def emit_commit(self):
self._exec("COMMIT")
@compiles(AddColumn, 'oracle')
def visit_add_column(element, compiler, **kw):
return "%s %s" % (
alter_table(compiler, element.table_name, element.schema),
add_column(compiler, element.column, **kw),
)
@compiles(ColumnNullable, 'oracle')
def visit_column_nullable(element, compiler, **kw):
return "%s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
"NULL" if element.nullable else "NOT NULL"
)
@compiles(ColumnType, 'oracle')
def visit_column_type(element, compiler, **kw):
return "%s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
"%s" % format_type(compiler, element.type_)
)
@compiles(ColumnName, 'oracle')
def visit_column_name(element, compiler, **kw):
return "%s RENAME COLUMN %s TO %s" % (
alter_table(compiler, element.table_name, element.schema),
format_column_name(compiler, element.column_name),
format_column_name(compiler, element.newname)
)
@compiles(ColumnDefault, 'oracle')
def visit_column_default(element, compiler, **kw):
return "%s %s %s" % (
alter_table(compiler, element.table_name, element.schema),
alter_column(compiler, element.column_name),
"DEFAULT %s" %
format_server_default(compiler, element.default)
if element.default is not None
else "DEFAULT NULL"
)
def alter_column(compiler, name):
return 'MODIFY %s' % format_column_name(compiler, name)
def add_column(compiler, column, **kw):
return "ADD %s" % compiler.get_column_specification(column, **kw)

View file

@ -0,0 +1,43 @@
import re
from sqlalchemy import types as sqltypes
from .base import compiles, alter_table, format_table_name, RenameTable
from .impl import DefaultImpl
class PostgresqlImpl(DefaultImpl):
__dialect__ = 'postgresql'
transactional_ddl = True
def compare_server_default(self, inspector_column,
metadata_column,
rendered_metadata_default,
rendered_inspector_default):
# don't do defaults for SERIAL columns
if metadata_column.primary_key and \
metadata_column is metadata_column.table._autoincrement_column:
return False
conn_col_default = rendered_inspector_default
if None in (conn_col_default, rendered_metadata_default):
return conn_col_default != rendered_metadata_default
if metadata_column.type._type_affinity is not sqltypes.String:
rendered_metadata_default = re.sub(r"^'|'$", "", rendered_metadata_default)
return not self.connection.scalar(
"SELECT %s = %s" % (
conn_col_default,
rendered_metadata_default
)
)
@compiles(RenameTable, "postgresql")
def visit_rename_table(element, compiler, **kw):
return "%s RENAME TO %s" % (
alter_table(compiler, element.table_name, element.schema),
format_table_name(compiler, element.new_table_name, None)
)

View file

@ -0,0 +1,73 @@
from .. import util
from .impl import DefaultImpl
#from sqlalchemy.ext.compiler import compiles
#from .base import AddColumn, alter_table
#from sqlalchemy.schema import AddConstraint
class SQLiteImpl(DefaultImpl):
__dialect__ = 'sqlite'
transactional_ddl = False
"""SQLite supports transactional DDL, but pysqlite does not:
see: http://bugs.python.org/issue10740
"""
def add_constraint(self, const):
# attempt to distinguish between an
# auto-gen constraint and an explicit one
if const._create_rule is None:
raise NotImplementedError(
"No support for ALTER of constraints in SQLite dialect")
elif const._create_rule(self):
util.warn("Skipping unsupported ALTER for "
"creation of implicit constraint")
def drop_constraint(self, const):
if const._create_rule is None:
raise NotImplementedError(
"No support for ALTER of constraints in SQLite dialect")
def correct_for_autogen_constraints(self, conn_unique_constraints, conn_indexes,
metadata_unique_constraints,
metadata_indexes):
def uq_sig(uq):
return tuple(sorted(uq.columns.keys()))
conn_unique_sigs = set(
uq_sig(uq)
for uq in conn_unique_constraints
)
for idx in list(metadata_unique_constraints):
# SQLite backend can't report on unnamed UNIQUE constraints,
# so remove these, unless we see an exact signature match
if idx.name is None and uq_sig(idx) not in conn_unique_sigs:
metadata_unique_constraints.remove(idx)
for idx in list(conn_unique_constraints):
# just in case we fix the backend such that it does report
# on them, blow them out of the reflected collection too otherwise
# they will come up as removed. if the backend supports this now,
# add a version check here for the dialect.
if idx.name is None:
conn_uniques.remove(idx)
#@compiles(AddColumn, 'sqlite')
#def visit_add_column(element, compiler, **kw):
# return "%s %s" % (
# alter_table(compiler, element.table_name, element.schema),
# add_column(compiler, element.column, **kw)
# )
#def add_column(compiler, column, **kw):
# text = "ADD COLUMN %s" % compiler.get_column_specification(column, **kw)
# # need to modify SQLAlchemy so that the CHECK associated with a Boolean
# # or Enum gets placed as part of the column constraints, not the Table
# # see ticket 98
# for const in column.constraints:
# text += compiler.process(AddConstraint(const))
# return text