2008-02-06 18:39:07 +00:00

80 lines
3.4 KiB
Python

from migrate.changeset import ansisql,exceptions
from sqlalchemy.databases import oracle as sa_base
import sqlalchemy as sa
OracleSchemaGenerator = sa_base.OracleSchemaGenerator
class OracleColumnGenerator(OracleSchemaGenerator,ansisql.ANSIColumnGenerator):
pass
class OracleColumnDropper(ansisql.ANSIColumnDropper):
pass
class OracleSchemaChanger(OracleSchemaGenerator,ansisql.ANSISchemaChanger):
def get_column_specification(self,column,**kwargs):
# Ignore the NOT NULL generated
override_nullable = kwargs.pop('override_nullable',None)
if override_nullable:
orig = column.nullable
column.nullable = True
ret=super(OracleSchemaChanger,self).get_column_specification(column,**kwargs)
if override_nullable:
column.nullable = orig
return ret
def visit_column(self,delta):
keys = delta.keys()
if 'type' in keys or 'nullable' in keys or 'default' in keys:
self._run_subvisit(delta,self._visit_column_change)
if 'name' in keys:
self._run_subvisit(delta,self._visit_column_name)
def _visit_column_change(self,table_name,col_name,delta):
if not hasattr(delta,'result_column'):
# Oracle needs the whole column definition, not just a lone name/type
raise exceptions.NotSupportedError(
"A column object is required to do this")
column = delta.result_column
# Oracle cannot drop a default once created, but it can set it to null.
# We'll do that if default=None
# http://forums.oracle.com/forums/message.jspa?messageID=1273234#1273234
dropdefault_hack = (column.default is None and 'default' in delta.keys())
# Oracle apparently doesn't like it when we say "not null" if 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()))
if dropdefault_hack:
column.default = sa.PassiveDefault(sa.func.null())
if notnull_hack:
column.nullable = True
colspec=self.get_column_specification(column,override_nullable=null_hack)
if null_hack:
colspec += ' NULL'
if notnull_hack:
column.nullable = False
if dropdefault_hack:
column.default = None
self.start_alter_table(table_name)
self.append("MODIFY ")
self.append(colspec)
class OracleConstraintCommon(object):
def get_constraint_name(self,cons):
# Oracle constraints can't guess their name like other DBs
if not cons.name:
raise exceptions.NotSupportedError(
"Oracle constraint names must be explicitly stated")
return cons.name
class OracleConstraintGenerator(OracleConstraintCommon,ansisql.ANSIConstraintGenerator):
pass
class OracleConstraintDropper(OracleConstraintCommon,ansisql.ANSIConstraintDropper):
pass
class OracleDialect(ansisql.ANSIDialect):
columngenerator = OracleColumnGenerator
columndropper = OracleColumnDropper
schemachanger = OracleSchemaChanger
constraintgenerator = OracleConstraintGenerator
constraintdropper = OracleConstraintDropper