From: Mike Bayer Date: Thu, 10 Jan 2013 21:20:57 +0000 (-0500) Subject: The "implicit" constraint generated by a X-Git-Tag: rel_0_4_2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b3bc2d877e9e23b35c2ec92645d5cd055468dbd1;p=thirdparty%2Fsqlalchemy%2Falembic.git The "implicit" constraint generated by a type such as Boolean or Enum will not generate an ALTER statement when run on SQlite, which does not support ALTER for the purpose of adding/removing constraints separate from the column def itself. While SQLite supports adding a CHECK constraint at the column level, SQLAlchemy would need modification to support this. A warning is emitted indicating this constraint cannot be added in this scenario. #98 --- diff --git a/alembic/ddl/sqlite.py b/alembic/ddl/sqlite.py index 09437137..df92d960 100644 --- a/alembic/ddl/sqlite.py +++ b/alembic/ddl/sqlite.py @@ -1,5 +1,44 @@ from alembic.ddl.impl import DefaultImpl +from alembic import util + +#from sqlalchemy.ext.compiler import compiles +#from alembic.ddl.base import AddColumn, alter_table +#from sqlalchemy.schema import AddConstraint class SQLiteImpl(DefaultImpl): __dialect__ = 'sqlite' transactional_ddl = True + + 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") + + +#@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 diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index 1dae555b..52087d71 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -8,6 +8,21 @@ Changelog .. changelog:: :version: 0.4.2 + .. change:: + :tags: bug, sqlite + :tickets: 98 + + The "implicit" constraint generated by a + type such as Boolean or Enum will not generate an + ALTER statement when run on SQlite, which does not + support ALTER for the purpose of adding/removing + constraints separate from the column def itself. + While SQLite supports adding a CHECK constraint + at the column level, SQLAlchemy would need modification + to support this. + A warning is emitted indicating this + constraint cannot be added in this scenario. + .. change:: :tags: bug :tickets: 96 diff --git a/tests/test_sqlite.py b/tests/test_sqlite.py new file mode 100644 index 00000000..8d514eeb --- /dev/null +++ b/tests/test_sqlite.py @@ -0,0 +1,42 @@ +from tests import op_fixture, assert_raises_message +from alembic import op, util +from sqlalchemy import Integer, Column, ForeignKey, \ + UniqueConstraint, Table, MetaData, String,\ + func, Boolean +from sqlalchemy.sql import table, column + +def test_add_column(): + context = op_fixture('sqlite') + op.add_column('t1', Column('c1', Integer)) + context.assert_( + 'ALTER TABLE t1 ADD COLUMN c1 INTEGER' + ) + +def test_add_column_implicit_constraint(): + context = op_fixture('sqlite') + op.add_column('t1', Column('c1', Boolean)) + context.assert_( + 'ALTER TABLE t1 ADD COLUMN c1 BOOLEAN' + ) + +def test_add_explicit_constraint(): + context = op_fixture('sqlite') + assert_raises_message( + NotImplementedError, + "No support for ALTER of constraints in SQLite dialect", + op.create_check_constraint, + "foo", + "sometable", + column('name') > 5 + ) + +def test_drop_explicit_constraint(): + context = op_fixture('sqlite') + assert_raises_message( + NotImplementedError, + "No support for ALTER of constraints in SQLite dialect", + op.drop_constraint, + "foo", + "sometable", + ) +