From: Mike Bayer Date: Sun, 25 Aug 2013 16:28:47 +0000 (-0400) Subject: added "system=True" to Column, so that we generally don't have to bother X-Git-Tag: rel_0_8_3~41 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0ac7e20d8b05935cc5ffb176fab2a2f82ca40a4;p=thirdparty%2Fsqlalchemy%2Fsqlalchemy.git added "system=True" to Column, so that we generally don't have to bother with CreateColumn rules --- diff --git a/doc/build/changelog/changelog_08.rst b/doc/build/changelog/changelog_08.rst index 31b420b611..91aa2f7e96 100644 --- a/doc/build/changelog/changelog_08.rst +++ b/doc/build/changelog/changelog_08.rst @@ -9,7 +9,12 @@ .. change:: :tags: feature - The :class:`.CreateColumn` construct can be appled to a custom + Added a new flag ``system=True`` to :class:`.Column`, which marks + the column as a "system" column which is automatically made present + by the database (such as Postgresql ``oid`` or ``xmin``). The + column will be omitted from the ``CREATE TABLE`` statement but will + otherwise be available for querying. In addition, the + :class:`.CreateColumn` construct can be appled to a custom compilation rule which allows skipping of columns, by producing a rule that returns ``None``. diff --git a/lib/sqlalchemy/schema.py b/lib/sqlalchemy/schema.py index bcd8f0e7a5..6cb024a110 100644 --- a/lib/sqlalchemy/schema.py +++ b/lib/sqlalchemy/schema.py @@ -892,6 +892,18 @@ class Column(SchemaItem, expression.ColumnClause): an explicit name, use the :class:`.UniqueConstraint` or :class:`.Index` constructs explicitly. + :param system: When ``True``, indicates this is a "system" column, + that is a column which is automatically made available by the + database, and should not be included in the columns list for a + ``CREATE TABLE`` statement. + + For more elaborate scenarios where columns should be conditionally + rendered differently on different backends, consider custom + compilation rules for :class:`.CreateColumn`. + + ..versionadded:: 0.8.3 Added the ``system=True`` parameter to + :class:`.Column`. + """ name = kwargs.pop('name', None) @@ -925,6 +937,7 @@ class Column(SchemaItem, expression.ColumnClause): self.server_onupdate = kwargs.pop('server_onupdate', None) self.index = kwargs.pop('index', None) self.unique = kwargs.pop('unique', None) + self.system = kwargs.pop('system', False) self.quote = kwargs.pop('quote', None) self.doc = kwargs.pop('doc', None) self.onupdate = kwargs.pop('onupdate', None) @@ -3459,13 +3472,18 @@ class CreateColumn(_DDLCompiles): 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``:: + This is essentially how to produce the same effect as using the + ``system=True`` argument on :class:`.Column`, which marks a column + as an implicitly-present "system" column. + + For example, suppose we wish to produce a :class:`.Table` which skips + rendering of the Postgresql ``xmin`` column against the Postgresql backend, + but on other backends does render it, in anticipation of a triggered rule. + A conditional compilation rule could skip this name only on Postgresql:: from sqlalchemy.schema import CreateColumn - @compiles(CreateColumn) + @compiles(CreateColumn, "postgresql") def skip_xmin(element, compiler, **kw): if element.element.name == 'xmin': return None @@ -3480,7 +3498,7 @@ class CreateColumn(_DDLCompiles): 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. + will be omitted, but only against the Postgresql backend. .. versionadded:: 0.8.3 The :class:`.CreateColumn` construct supports skipping of columns by returning ``None`` from a custom compilation rule. diff --git a/lib/sqlalchemy/sql/compiler.py b/lib/sqlalchemy/sql/compiler.py index fcd137fbde..13bf47c0b1 100644 --- a/lib/sqlalchemy/sql/compiler.py +++ b/lib/sqlalchemy/sql/compiler.py @@ -1965,6 +1965,9 @@ class DDLCompiler(engine.Compiled): def visit_create_column(self, create, first_pk=False): column = create.element + if column.system: + return None + text = self.get_column_specification( column, first_pk=first_pk diff --git a/test/sql/test_compiler.py b/test/sql/test_compiler.py index 7736d2335d..1c2ff037d3 100644 --- a/test/sql/test_compiler.py +++ b/test/sql/test_compiler.py @@ -2727,6 +2727,15 @@ class DDLTest(fixtures.TestBase, AssertsCompiledSQL): schema.CreateTable(t1).compile ) + def test_system_flag(self): + m = MetaData() + t = Table('t', m, Column('x', Integer), + Column('y', Integer, system=True), + Column('z', Integer)) + self.assert_compile( + schema.CreateTable(t), + "CREATE TABLE t (x INTEGER, z INTEGER)" + ) class InlineDefaultTest(fixtures.TestBase, AssertsCompiledSQL): __dialect__ = 'default'