From: Mike Bayer Date: Fri, 3 Oct 2014 15:12:19 +0000 (-0400) Subject: - Added support for use of the :class:`~sqlalchemy.sql.elements.quoted_name` X-Git-Tag: rel_0_7_0~64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5bb97a4b094bd6aac0a47f2c7ad268b57cd4b32d;p=thirdparty%2Fsqlalchemy%2Falembic.git - Added support for use of the :class:`~sqlalchemy.sql.elements.quoted_name` construct when using the ``schema`` argument within operations. This allows a name containing a dot to be fully quoted, as well as to provide configurable quoting on a per-name basis. fixes #230 --- diff --git a/alembic/ddl/base.py b/alembic/ddl/base.py index 3a609262..aa5fbe16 100644 --- a/alembic/ddl/base.py +++ b/alembic/ddl/base.py @@ -4,6 +4,10 @@ from sqlalchemy.ext.compiler import compiles from sqlalchemy.schema import DDLElement, Column from sqlalchemy import Integer from sqlalchemy import types as sqltypes +from .. import util + +if util.sqla_09: + from sqlalchemy.sql.elements import quoted_name class AlterTable(DDLElement): @@ -151,6 +155,8 @@ def visit_column_default(element, compiler, **kw): def quote_dotted(name, quote): """quote the elements of a dotted name""" + if util.sqla_09 and isinstance(name, quoted_name): + return quote(name) result = '.'.join([quote(x) for x in name.split('.')]) return result diff --git a/alembic/operations.py b/alembic/operations.py index 2ea54cb3..9124f328 100644 --- a/alembic/operations.py +++ b/alembic/operations.py @@ -199,7 +199,15 @@ class Operations(object): :param old_table_name: old name. :param new_table_name: new name. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. + + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ self.impl.rename_table( @@ -293,9 +301,15 @@ class Operations(object): :param existing_autoincrement: Optional; the existing autoincrement of the column. Used for MySQL's system of altering a column that specifies ``AUTO_INCREMENT``. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. - .. versionadded:: 0.4.0 + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ @@ -432,9 +446,16 @@ class Operations(object): :param table_name: String name of the parent table. :param column: a :class:`sqlalchemy.schema.Column` object representing the new column. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. + + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. - .. versionadded:: 0.4.0 """ @@ -458,9 +479,15 @@ class Operations(object): :param table_name: name of table :param column_name: name of column - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. - .. versionadded:: 0.4.0 + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. :param mssql_drop_check: Optional boolean. When ``True``, on Microsoft SQL Server only, first @@ -527,7 +554,15 @@ class Operations(object): :param table_name: String name of the target table. :param cols: a list of string column names to be applied to the primary key constraint. - :param schema: Optional schema name of the table. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. + + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ self.impl.add_constraint( @@ -630,9 +665,15 @@ class Operations(object): NOT DEFERRABLE when issuing DDL for this constraint. :param initially: optional string. If set, emit INITIALLY when issuing DDL for this constraint. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. - .. versionadded:: 0.4.0 + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ @@ -677,9 +718,15 @@ class Operations(object): NOT DEFERRABLE when issuing DDL for this constraint. :param initially: optional string. If set, emit INITIALLY when issuing DDL for this constraint. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. + + .. versionadded:: 0.4.0 support for 'schema' - ..versionadded:: 0.4.0 + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ self.impl.add_constraint( @@ -728,7 +775,15 @@ class Operations(object): the table, as well as optional :class:`~sqlalchemy.schema.Constraint` objects and :class:`~.sqlalchemy.schema.Index` objects. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. + + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. :param \**kw: Other keyword arguments are passed to the underlying :class:`sqlalchemy.schema.Table` object created for the command. @@ -747,7 +802,15 @@ class Operations(object): drop_table("accounts") :param name: Name of the table - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. + + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. .. versionadded:: 0.4.0 @@ -791,9 +854,15 @@ class Operations(object): :param columns: a list consisting of string column names and/or :func:`~sqlalchemy.sql.expression.text` constructs. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. - .. versionadded:: 0.4.0 + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ @@ -819,9 +888,15 @@ class Operations(object): The old name will continue to function for backwards compatibility. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. - .. versionadded:: 0.4.0 + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ # need a dummy column name here since SQLAlchemy @@ -852,9 +927,15 @@ class Operations(object): .. versionadded:: 0.3.6 'primary' qualfier to enable dropping of MySQL primary key constraints. - :param schema: Optional schema name to operate within. + :param schema: Optional schema name to operate within. To control + quoting of the schema outside of the default behavior, use + the SQLAlchemy construct + :class:`~sqlalchemy.sql.elements.quoted_name`. - .. versionadded:: 0.4.0 + .. versionadded:: 0.4.0 support for 'schema' + + .. versionadded:: 0.7.0 'schema' can now accept a + :class:`~sqlalchemy.sql.elements.quoted_name` construct. """ diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index ba726802..0cf41dd5 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -5,6 +5,15 @@ Changelog .. changelog:: :version: 0.7.0 + .. change:: + :tags: bug, operations + :tickets: 230 + + Added support for use of the :class:`~sqlalchemy.sql.elements.quoted_name` + construct when using the ``schema`` argument within operations. This + allows a name containing a dot to be fully quoted, as well as to + provide configurable quoting on a per-name basis. + .. change:: :tags: bug, autogenerate, postgresql :tickets: 73 diff --git a/tests/test_op.py b/tests/test_op.py index 13e58bd4..54349007 100644 --- a/tests/test_op.py +++ b/tests/test_op.py @@ -49,6 +49,45 @@ class OpTest(TestBase): op.create_index, 'name', 'tname', [func.foo(column('x'))] ) + @config.requirements.sqlalchemy_09 + def test_add_column_schema_hard_quoting(self): + from sqlalchemy.sql.schema import quoted_name + context = op_fixture("postgresql") + op.add_column( + "somename", Column("colname", String), + schema=quoted_name("some.schema", quote=True)) + + context.assert_( + 'ALTER TABLE "some.schema".somename ADD COLUMN colname VARCHAR' + ) + + @config.requirements.sqlalchemy_09 + def test_rename_table_schema_hard_quoting(self): + from sqlalchemy.sql.schema import quoted_name + context = op_fixture("postgresql") + op.rename_table( + 't1', 't2', + schema=quoted_name("some.schema", quote=True)) + + context.assert_( + 'ALTER TABLE "some.schema".t1 RENAME TO t2' + ) + + @config.requirements.sqlalchemy_09 + def test_add_constraint_schema_hard_quoting(self): + from sqlalchemy.sql.schema import quoted_name + context = op_fixture("postgresql") + op.create_check_constraint( + "ck_user_name_len", + "user_table", + func.len(column('name')) > 5, + schema=quoted_name("some.schema", quote=True) + ) + context.assert_( + 'ALTER TABLE "some.schema".user_table ADD ' + 'CONSTRAINT ck_user_name_len CHECK (len(name) > 5)' + ) + def test_create_index_quoting(self): context = op_fixture("postgresql") op.create_index(