]> git.ipfire.org Git - thirdparty/sqlalchemy/alembic.git/commitdiff
- support SQLAlchemy ticket 2742 by ensuring that expressions in DDL are rendered
authorMike Bayer <mike_mp@zzzcomputing.com>
Wed, 13 Nov 2013 15:03:55 +0000 (10:03 -0500)
committerMike Bayer <mike_mp@zzzcomputing.com>
Wed, 13 Nov 2013 15:03:55 +0000 (10:03 -0500)
(at least in indexes for now) using literal_binds=True, resolve #155

alembic/autogenerate/render.py
alembic/compat.py
tests/test_autogenerate.py

index c471182bf610565272ebc4dc6aea22cac10597c5..0f31dbca3b55743235c4ea6fb80843e7d5b16ec4 100644 (file)
@@ -1,5 +1,6 @@
-from sqlalchemy import schema as sa_schema, types as sqltypes
+from sqlalchemy import schema as sa_schema, types as sqltypes, sql
 import logging
+from .. import compat
 import re
 
 
@@ -7,6 +8,17 @@ from ..compat import string_types, get_index_column_names
 
 log = logging.getLogger(__name__)
 
+def _render_potential_expr(value, autogen_context):
+    if isinstance(value, sql.ClauseElement):
+        if compat.sqla_08:
+            return str(
+                value.compile(dialect=autogen_context['dialect'],
+                    compile_kwargs={'literal_binds': True}))
+        else:
+            return str(value.compile(dialect=autogen_context['dialect']))
+    else:
+        return str(value)
+
 def _add_table(table, autogen_context):
     text = "%(prefix)screate_table(%(tablename)r,\n%(args)s" % {
         'tablename': table.name,
@@ -51,7 +63,8 @@ def _add_index(index, autogen_context):
         'unique': index.unique or False,
         'schema': (", schema='%s'" % index.table.schema) if index.table.schema else '',
         'kwargs': (', '+', '.join(
-            ["%s='%s'" % (key, val) for key, val in index.kwargs.items()]))\
+            ["%s=%r" % (key, _render_potential_expr(val, autogen_context))
+                for key, val in index.kwargs.items()]))\
             if len(index.kwargs) else ''
     }
     return text
index 7d0357dccd67a85338f19817ed94f2458e45f9da..0f066aa95a57aabd274eb16c0769a87e1f07ff23 100644 (file)
@@ -4,6 +4,9 @@ from sqlalchemy import __version__ as sa_version
 if sys.version_info < (2, 6):
     raise NotImplementedError("Python 2.6 or greater is required.")
 
+sqla_08 = sa_version >= '0.8.0'
+sqla_09 = sa_version >= '0.9.0'
+
 py2k = sys.version_info < (3, 0)
 py3k = sys.version_info >= (3, 0)
 py33 = sys.version_info >= (3, 3)
index aaaebd21ff2d360e13acb6ae4a7547fb67ed735a..d61945db0e081409dfd1595187e41d52bdf869b0 100644 (file)
@@ -9,11 +9,11 @@ from sqlalchemy import MetaData, Column, Table, Integer, String, Text, \
     UniqueConstraint, Boolean, ForeignKeyConstraint,\
     PrimaryKeyConstraint, Index, func
 from sqlalchemy.types import NULLTYPE, TIMESTAMP
-from sqlalchemy.dialects import mysql
+from sqlalchemy.dialects import mysql, postgresql
 from sqlalchemy.engine.reflection import Inspector
 from sqlalchemy.sql import and_, column, literal_column
 
-from alembic import autogenerate, util
+from alembic import autogenerate, util, compat
 from alembic.migration import MigrationContext
 from . import staging_env, sqlite_db, clear_staging_env, eq_, \
         eq_ignore_whitespace, requires_07, db_for_dialect
@@ -1078,6 +1078,14 @@ class AutogenRenderTest(TestCase):
             },
             'dialect': mysql.dialect()
         }
+        cls.pg_autogen_context = {
+            'opts': {
+                'sqlalchemy_module_prefix': 'sa.',
+                'alembic_module_prefix': 'op.',
+            },
+            'dialect': postgresql.dialect()
+        }
+
 
     def test_render_add_index(self):
         """
@@ -1114,6 +1122,31 @@ class AutogenRenderTest(TestCase):
             "['active', 'code'], unique=False, schema='CamelSchema')"
         )
 
+    def test_render_add_index_pg_where(self):
+        autogen_context = self.pg_autogen_context
+
+        m = MetaData()
+        t = Table('t', m,
+            Column('x', String),
+            Column('y', String)
+            )
+
+        idx = Index('foo_idx', t.c.x, t.c.y,
+                            postgresql_where=(t.c.y == 'something'))
+
+        if compat.sqla_08:
+            eq_ignore_whitespace(
+                autogenerate.render._add_index(idx, autogen_context),
+                """op.create_index('foo_idx', 't', ['x', 'y'], unique=False, """
+                    """postgresql_where="t.y = 'something'")"""
+            )
+        else:
+            eq_ignore_whitespace(
+                autogenerate.render._add_index(idx, autogen_context),
+                """op.create_index('foo_idx', 't', ['x', 'y'], unique=False, """
+                    """postgresql_where='t.y = %(y_1)s')"""
+            )
+
     # def test_render_add_index_func(self):
     #     """
     #     autogenerate.render._drop_index using func -- TODO: SQLA needs to