]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
Dont autogenerate "system=True", render flag correctly
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 24 Oct 2018 17:44:09 +0000 (13:44 -0400)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 31 Oct 2018 18:42:51 +0000 (14:42 -0400)
The ``system=True`` flag on :class:`.Column`, used primarily in conjunction
with the Postgresql "xmin" column, now renders within the autogenerate
render process, allowing the column to be excluded from DDL.  Additionally,
adding a system=True column to a model will produce no autogenerate diff as
this column is implicitly present in the database.

Change-Id: Ie3aab9d489ebb9aecccbdf9d5b3ce8ccc42554bf
Fixes: #515
alembic/autogenerate/compare.py
alembic/autogenerate/render.py
docs/build/unreleased/515.rst [new file with mode: 0644]
tests/test_autogen_diffs.py
tests/test_autogen_render.py

index 1b660613fd17d87e51c3b6489c8de7bed30346c7..8b416475c0f446cd29547c1f1a2d7d1ce80f37d2 100644 (file)
@@ -241,7 +241,8 @@ def _make_foreign_key(params, conn_table):
 def _compare_columns(schema, tname, conn_table, metadata_table,
                      modify_table_ops, autogen_context, inspector):
     name = '%s.%s' % (schema, tname) if schema else tname
-    metadata_cols_by_name = dict((c.name, c) for c in metadata_table.c)
+    metadata_cols_by_name = dict(
+        (c.name, c) for c in metadata_table.c if not c.system)
     conn_col_names = dict((c.name, c) for c in conn_table.c)
     metadata_col_names = OrderedSet(sorted(metadata_cols_by_name))
 
index ed289a6c0051a5a3bccbaa877a5b1c1b42a06afe..4fbe91fd07d539b7ca43c7f8d5289f2d9c500562 100644 (file)
@@ -534,6 +534,9 @@ def _render_column(column, autogen_context):
     if column.nullable is not None:
         opts.append(("nullable", column.nullable))
 
+    if column.system:
+        opts.append(("system", column.system))
+
     # TODO: for non-ascii colname, assign a "key"
     return "%(prefix)sColumn(%(name)r, %(type)s, %(kw)s)" % {
         'prefix': _sqlalchemy_autogenerate_prefix(autogen_context),
diff --git a/docs/build/unreleased/515.rst b/docs/build/unreleased/515.rst
new file mode 100644 (file)
index 0000000..73cf85d
--- /dev/null
@@ -0,0 +1,9 @@
+.. change::
+   :tags: bug, autogenerate
+   :tickets: 515
+
+   The ``system=True`` flag on :class:`.Column`, used primarily in conjunction
+   with the Postgresql "xmin" column, now renders within the autogenerate
+   render process, allowing the column to be excluded from DDL.  Additionally,
+   adding a system=True column to a model will produce no autogenerate diff as
+   this column is implicitly present in the database.
index 85f87a31699949bac0ec1385cf6b6c2d71c9c289..38e06b6cfe5c19cb15ccb0555e035080877da2cc 100644 (file)
@@ -675,6 +675,40 @@ class CompareTypeSpecificityTest(TestBase):
         is_(impl.compare_type(Column('x', t2), Column('x', t3)), True)
 
 
+class AutogenSystemColTest(AutogenTest, TestBase):
+    __only_on__ = 'postgresql'
+
+    @classmethod
+    def _get_db_schema(cls):
+        m = MetaData()
+
+        Table(
+            'sometable', m,
+            Column('id', Integer, primary_key=True),
+        )
+        return m
+
+    @classmethod
+    def _get_model_schema(cls):
+        m = MetaData()
+
+        # 'xmin' is implicitly present, when added to a model should produce
+        # no change
+        Table(
+            'sometable', m,
+            Column('id', Integer, primary_key=True),
+            Column('xmin', Integer, system=True)
+        )
+        return m
+
+    def test_dont_add_system(self):
+        uo = ops.UpgradeOps(ops=[])
+        autogenerate._produce_net_changes(self.autogen_context, uo)
+
+        diffs = uo.as_diffs()
+        eq_(diffs, [])
+
+
 class AutogenerateVariantCompareTest(AutogenTest, TestBase):
     __backend__ = True
 
@@ -1134,7 +1168,6 @@ class PGCompareMetaData(ModelOne, AutogenTest, TestBase):
         eq_(diffs[5][0][5], False)
         eq_(diffs[5][0][6], True)
 
-
 class OrigObjectTest(TestBase):
     def setUp(self):
         self.metadata = m = MetaData()
index 2bc8d825c66a9be86baa9ba2edd0d30de96565f0..b32358fa0ad7e5dba17086866979dd72e5977fea 100644 (file)
@@ -688,6 +688,21 @@ class AutogenRenderTest(TestBase):
             ")"
         )
 
+    def test_render_table_w_system(self):
+        m = MetaData()
+        t = Table('sometable', m,
+                  Column('id', Integer, primary_key=True),
+                  Column('xmin', Integer, system=True, nullable=False)
+                  )
+        op_obj = ops.CreateTableOp.from_table(t)
+        eq_ignore_whitespace(
+            autogenerate.render_op_text(self.autogen_context, op_obj),
+            "op.create_table('sometable',"
+            "sa.Column('id', sa.Integer(), nullable=False),"
+            "sa.Column('xmin', sa.Integer(), nullable=False, system=True),"
+            "sa.PrimaryKeyConstraint('id'))"
+        )
+
     def test_render_table_w_unicode_name(self):
         m = MetaData()
         t = Table(compat.ue('\u0411\u0435\u0437'), m,
@@ -937,6 +952,18 @@ class AutogenRenderTest(TestBase):
             "server_default='5', nullable=True))"
         )
 
+    def test_render_add_column_system(self):
+        # this would never actually happen since "system" columns
+        # can't be added in any case.   Howver it will render as
+        # part of op.CreateTableOp.
+        op_obj = ops.AddColumnOp(
+            "foo", Column("xmin", Integer, system=True))
+        eq_ignore_whitespace(
+            autogenerate.render_op_text(self.autogen_context, op_obj),
+            "op.add_column('foo', sa.Column('xmin', sa.Integer(), "
+            "nullable=True, system=True))"
+        )
+
     def test_render_add_column_w_schema(self):
         op_obj = ops.AddColumnOp(
             "bar", Column("x", Integer, server_default="5"),