From: Mike Bayer Date: Sat, 24 Aug 2013 17:55:14 +0000 (-0400) Subject: - The :class:`.CreateColumn` construct can be appled to a custom X-Git-Tag: rel_0_8_3~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=58617ff5ff2facafdc6d17f7115a338daf878629;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git - The :class:`.CreateColumn` construct can be appled to a custom compilation rule which allows skipping of columns, by producing a rule that returns ``None``. Also in 0.8.3. Conflicts: doc/build/changelog/changelog_09.rst lib/sqlalchemy/sql/ddl.py --- diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 43dcf7c515..31b420b611 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -6,6 +6,13 @@ .. changelog:: :version: 0.8.3 + .. change:: + :tags: feature + + The :class:`.CreateColumn` construct can be appled to a custom + compilation rule which allows skipping of columns, by producing + a rule that returns ``None``. + .. change:: :tags: bug, orm :tickets: 2807 diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index 062c3c04e2..bcd8f0e7a5 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -3456,6 +3456,35 @@ class CreateColumn(_DDLCompiles): PRIMARY KEY (x) ) + The :class:`.CreateColumn` construct can also be used to skip certain + columns when producing a ``CREATE TABLE``. This is accomplished by + creating a compilation rule that conditionally returns ``None``. + For example, to produce a + :class:`.Table` which includes the Postgresql system column ``xmin``, + but omits this column from the ``CREATE TABLE``:: + + from sqlalchemy.schema import CreateColumn + + @compiles(CreateColumn) + def skip_xmin(element, compiler, **kw): + if element.element.name == 'xmin': + return None + else: + return compiler.visit_create_column(element, **kw) + + + my_table = Table('mytable', metadata, + Column('id', Integer, primary_key=True), + Column('xmin', Integer) + ) + + Above, a :class:`.CreateTable` construct will generate a ``CREATE TABLE`` + which only includes the ``id`` column in the string; the ``xmin`` column + will be omitted. + + .. versionadded:: 0.8.3 The :class:`.CreateColumn` construct supports + skipping of columns by returning ``None`` from a custom compilation rule. + .. versionadded:: 0.8 The :class:`.CreateColumn` construct was added to support custom column creation styles. diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index 01959ee18e..fcd137fbde 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1929,11 +1929,13 @@ class DDLCompiler(engine.Compiled): for create_column in create.columns: column = create_column.element try: - text += separator - separator = ", \n" - text += "\t" + self.process(create_column, + processed = self.process(create_column, first_pk=column.primary_key and not first_pk) + if processed is not None: + text += separator + separator = ", \n" + text += "\t" + processed if column.primary_key: first_pk = True except exc.CompileError, ce: diff --git a/test/ext/test_compiler.py b/test/ext/test_compiler.py index c1f8b62589..5ed50442f7 100644 --- a/test/ext/test_compiler.py +++ b/test/ext/test_compiler.py @@ -4,7 +4,7 @@ from sqlalchemy.sql.expression import ClauseElement, ColumnClause,\ FunctionElement, Select, \ BindParameter -from sqlalchemy.schema import DDLElement +from sqlalchemy.schema import DDLElement, CreateColumn, CreateTable from sqlalchemy.ext.compiler import compiles, deregister from sqlalchemy import exc from sqlalchemy.sql import table, column, visitors @@ -34,6 +34,22 @@ class UserDefinedTest(fixtures.TestBase, AssertsCompiledSQL): "SELECT >>x<<, >>y<< WHERE >>MYTHINGY!<< = :MYTHINGY!_1" ) + def test_create_column_skip(self): + @compiles(CreateColumn) + def skip_xmin(element, compiler, **kw): + if element.element.name == 'xmin': + return None + else: + return compiler.visit_create_column(element, **kw) + + t = Table('t', MetaData(), Column('a', Integer), + Column('xmin', Integer), + Column('c', Integer)) + + self.assert_compile( + CreateTable(t), + "CREATE TABLE t (a INTEGER, c INTEGER)" + ) def test_types(self): class MyType(TypeEngine): pass