Skip to content

Commit 2452c49

Browse files
committed
added "system=True" to Column, so that we generally don't have to bother
with CreateColumn rules
1 parent b3aa038 commit 2452c49

File tree

6 files changed

+47
-7
lines changed

6 files changed

+47
-7
lines changed

doc/build/changelog/changelog_08.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
.. change::
1010
:tags: feature
1111

12-
The :class:`.CreateColumn` construct can be appled to a custom
12+
Added a new flag ``system=True`` to :class:`.Column`, which marks
13+
the column as a "system" column which is automatically made present
14+
by the database (such as Postgresql ``oid`` or ``xmin``). The
15+
column will be omitted from the ``CREATE TABLE`` statement but will
16+
otherwise be available for querying. In addition, the
17+
:class:`.CreateColumn` construct can be appled to a custom
1318
compilation rule which allows skipping of columns, by producing
1419
a rule that returns ``None``.
1520

doc/build/changelog/changelog_09.rst

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,12 @@
99
.. change::
1010
:tags: feature
1111

12-
The :class:`.CreateColumn` construct can be appled to a custom
12+
Added a new flag ``system=True`` to :class:`.Column`, which marks
13+
the column as a "system" column which is automatically made present
14+
by the database (such as Postgresql ``oid`` or ``xmin``). The
15+
column will be omitted from the ``CREATE TABLE`` statement but will
16+
otherwise be available for querying. In addition, the
17+
:class:`.CreateColumn` construct can be appled to a custom
1318
compilation rule which allows skipping of columns, by producing
1419
a rule that returns ``None``. Also in 0.8.3.
1520

lib/sqlalchemy/sql/compiler.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2205,6 +2205,9 @@ def visit_create_table(self, create):
22052205
def visit_create_column(self, create, first_pk=False):
22062206
column = create.element
22072207

2208+
if column.system:
2209+
return None
2210+
22082211
text = self.get_column_specification(
22092212
column,
22102213
first_pk=first_pk

lib/sqlalchemy/sql/ddl.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -551,13 +551,18 @@ def compile(element, compiler, **kw):
551551
The :class:`.CreateColumn` construct can also be used to skip certain
552552
columns when producing a ``CREATE TABLE``. This is accomplished by
553553
creating a compilation rule that conditionally returns ``None``.
554-
For example, to produce a
555-
:class:`.Table` which includes the Postgresql system column ``xmin``,
556-
but omits this column from the ``CREATE TABLE``::
554+
This is essentially how to produce the same effect as using the
555+
``system=True`` argument on :class:`.Column`, which marks a column
556+
as an implicitly-present "system" column.
557+
558+
For example, suppose we wish to produce a :class:`.Table` which skips
559+
rendering of the Postgresql ``xmin`` column against the Postgresql backend,
560+
but on other backends does render it, in anticipation of a triggered rule.
561+
A conditional compilation rule could skip this name only on Postgresql::
557562
558563
from sqlalchemy.schema import CreateColumn
559564
560-
@compiles(CreateColumn)
565+
@compiles(CreateColumn, "postgresql")
561566
def skip_xmin(element, compiler, **kw):
562567
if element.element.name == 'xmin':
563568
return None
@@ -572,7 +577,7 @@ def skip_xmin(element, compiler, **kw):
572577
573578
Above, a :class:`.CreateTable` construct will generate a ``CREATE TABLE``
574579
which only includes the ``id`` column in the string; the ``xmin`` column
575-
will be omitted.
580+
will be omitted, but only against the Postgresql backend.
576581
577582
.. versionadded:: 0.8.3 The :class:`.CreateColumn` construct supports
578583
skipping of columns by returning ``None`` from a custom compilation rule.

lib/sqlalchemy/sql/schema.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -893,6 +893,18 @@ def __init__(self, *args, **kwargs):
893893
an explicit name, use the :class:`.UniqueConstraint` or
894894
:class:`.Index` constructs explicitly.
895895
896+
:param system: When ``True``, indicates this is a "system" column,
897+
that is a column which is automatically made available by the
898+
database, and should not be included in the columns list for a
899+
``CREATE TABLE`` statement.
900+
901+
For more elaborate scenarios where columns should be conditionally
902+
rendered differently on different backends, consider custom
903+
compilation rules for :class:`.CreateColumn`.
904+
905+
..versionadded:: 0.8.3 Added the ``system=True`` parameter to
906+
:class:`.Column`.
907+
896908
"""
897909

898910
name = kwargs.pop('name', None)
@@ -922,6 +934,7 @@ def __init__(self, *args, **kwargs):
922934
self.server_onupdate = kwargs.pop('server_onupdate', None)
923935
self.index = kwargs.pop('index', None)
924936
self.unique = kwargs.pop('unique', None)
937+
self.system = kwargs.pop('system', False)
925938
self.quote = kwargs.pop('quote', None)
926939
self.doc = kwargs.pop('doc', None)
927940
self.onupdate = kwargs.pop('onupdate', None)

test/sql/test_compiler.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2800,6 +2800,15 @@ def test_reraise_of_column_spec_issue_unicode(self):
28002800
schema.CreateTable(t1).compile
28012801
)
28022802

2803+
def test_system_flag(self):
2804+
m = MetaData()
2805+
t = Table('t', m, Column('x', Integer),
2806+
Column('y', Integer, system=True),
2807+
Column('z', Integer))
2808+
self.assert_compile(
2809+
schema.CreateTable(t),
2810+
"CREATE TABLE t (x INTEGER, z INTEGER)"
2811+
)
28032812

28042813
class InlineDefaultTest(fixtures.TestBase, AssertsCompiledSQL):
28052814
__dialect__ = 'default'

0 commit comments

Comments
 (0)