diff options
author | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-11-17 12:09:28 -0500 |
---|---|---|
committer | Mike Bayer <mike_mp@zzzcomputing.com> | 2014-11-17 12:09:28 -0500 |
commit | 3cdc316b3b51a488ab0864a950a5ba4e1ac342a9 (patch) | |
tree | 5738fb24dfad4d3167d97a875b865a66eba3ed8c | |
parent | ec7afc5cbfba48bdd2f279ba25a7ebdfd0dcef78 (diff) | |
parent | a02719dcca8f10d227f6e8fcfcb4b042a9e36cf7 (diff) | |
download | alembic-3cdc316b3b51a488ab0864a950a5ba4e1ac342a9.tar.gz |
Merge branch 'master' into multi_branch
Conflicts:
docs/build/changelog.rst
-rw-r--r-- | alembic/autogenerate/render.py | 86 | ||||
-rw-r--r-- | alembic/compat.py | 31 | ||||
-rw-r--r-- | alembic/testing/assertions.py | 10 | ||||
-rw-r--r-- | alembic/testing/exclusions.py | 2 | ||||
-rw-r--r-- | docs/build/changelog.rst | 13 | ||||
-rw-r--r-- | tests/test_autogen_render.py | 141 |
6 files changed, 216 insertions, 67 deletions
diff --git a/alembic/autogenerate/render.py b/alembic/autogenerate/render.py index 5fdfe36..d14842e 100644 --- a/alembic/autogenerate/render.py +++ b/alembic/autogenerate/render.py @@ -28,7 +28,33 @@ class _f_name(object): self.name = name def __repr__(self): - return "%sf(%r)" % (self.prefix, self.name) + return "%sf(%r)" % (self.prefix, _ident(self.name)) + + +def _ident(name): + """produce a __repr__() object for a string identifier that may + use quoted_name() in SQLAlchemy 0.9 and greater. + + The issue worked around here is that quoted_name() doesn't have + very good repr() behavior by itself when unicode is involved. + + """ + if name is None: + return name + elif compat.sqla_09 and isinstance(name, sql.elements.quoted_name): + if compat.py2k: + # the attempt to encode to ascii here isn't super ideal, + # however we are trying to cut down on an explosion of + # u'' literals only when py2k + SQLA 0.9, in particular + # makes unit tests testing code generation very difficult + try: + return name.encode('ascii') + except UnicodeError: + return compat.text_type(name) + else: + return compat.text_type(name) + elif isinstance(name, compat.string_types): + return name def _render_potential_expr(value, autogen_context, wrap_in_text=True): @@ -45,7 +71,7 @@ def _render_potential_expr(value, autogen_context, wrap_in_text=True): return template % { "prefix": _sqlalchemy_autogenerate_prefix(autogen_context), - "sql": str( + "sql": compat.text_type( value.compile(dialect=autogen_context['dialect'], **compile_kw) ) @@ -71,12 +97,12 @@ def _add_table(table, autogen_context): args = ',\n'.join(args) text = "%(prefix)screate_table(%(tablename)r,\n%(args)s" % { - 'tablename': table.name, + 'tablename': _ident(table.name), 'prefix': _alembic_autogenerate_prefix(autogen_context), 'args': args, } if table.schema: - text += ",\nschema=%r" % table.schema + text += ",\nschema=%r" % _ident(table.schema) for k in sorted(table.kwargs): text += ",\n%s=%r" % (k.replace(" ", "_"), table.kwargs[k]) text += "\n)" @@ -86,22 +112,23 @@ def _add_table(table, autogen_context): def _drop_table(table, autogen_context): text = "%(prefix)sdrop_table(%(tname)r" % { "prefix": _alembic_autogenerate_prefix(autogen_context), - "tname": table.name + "tname": _ident(table.name) } if table.schema: - text += ", schema=%r" % table.schema + text += ", schema=%r" % _ident(table.schema) text += ")" return text def _get_index_rendered_expressions(idx, autogen_context): if compat.sqla_08: - return [repr(getattr(exp, "name", None)) + return [repr(_ident(getattr(exp, "name", None))) if isinstance(exp, sa_schema.Column) else _render_potential_expr(exp, autogen_context) for exp in idx.expressions] else: - return [repr(getattr(col, "name", None)) for col in idx.columns] + return [ + repr(_ident(getattr(col, "name", None))) for col in idx.columns] def _add_index(index, autogen_context): @@ -110,15 +137,15 @@ def _add_index(index, autogen_context): :class:`~sqlalchemy.schema.Index` instance. """ - text = "%(prefix)screate_index(%(name)r, '%(table)s', [%(columns)s], "\ + text = "%(prefix)screate_index(%(name)r, %(table)r, [%(columns)s], "\ "unique=%(unique)r%(schema)s%(kwargs)s)" % { 'prefix': _alembic_autogenerate_prefix(autogen_context), 'name': _render_gen_name(autogen_context, index.name), - 'table': index.table.name, + 'table': _ident(index.table.name), 'columns': ", ".join( _get_index_rendered_expressions(index, autogen_context)), 'unique': index.unique or False, - 'schema': (", schema='%s'" % index.table.schema) + 'schema': (", schema=%r" % _ident(index.table.schema)) if index.table.schema else '', 'kwargs': ( ', ' + @@ -137,11 +164,11 @@ def _drop_index(index, autogen_context): :class:`~sqlalchemy.schema.Index` instance. """ text = "%(prefix)sdrop_index(%(name)r, "\ - "table_name='%(table_name)s'%(schema)s)" % { + "table_name=%(table_name)r%(schema)s)" % { 'prefix': _alembic_autogenerate_prefix(autogen_context), 'name': _render_gen_name(autogen_context, index.name), - 'table_name': index.table.name, - 'schema': ((", schema='%s'" % index.table.schema) + 'table_name': _ident(index.table.name), + 'schema': ((", schema=%r" % _ident(index.table.schema)) if index.table.schema else '') } return text @@ -173,23 +200,25 @@ def _uq_constraint(constraint, autogen_context, alter): if constraint.initially: opts.append(("initially", str(constraint.initially))) if not has_batch and alter and constraint.table.schema: - opts.append(("schema", str(constraint.table.schema))) + opts.append(("schema", _ident(constraint.table.schema))) if not alter and constraint.name: opts.append( - ("name", _render_gen_name(autogen_context, constraint.name))) + ("name", + _render_gen_name(autogen_context, constraint.name))) if alter: - args = [repr(_render_gen_name(autogen_context, constraint.name))] + args = [ + repr(_render_gen_name(autogen_context, constraint.name))] if not has_batch: - args += [repr(constraint.table.name)] - args.append(repr([col.name for col in constraint.columns])) + args += [repr(_ident(constraint.table.name))] + args.append(repr([_ident(col.name) for col in constraint.columns])) args.extend(["%s=%r" % (k, v) for k, v in opts]) return "%(prefix)screate_unique_constraint(%(args)s)" % { 'prefix': _alembic_autogenerate_prefix(autogen_context), 'args': ", ".join(args) } else: - args = [repr(col.name) for col in constraint.columns] + args = [repr(_ident(col.name)) for col in constraint.columns] args.extend(["%s=%r" % (k, v) for k, v in opts]) return "%(prefix)sUniqueConstraint(%(args)s)" % { "prefix": _sqlalchemy_autogenerate_prefix(autogen_context), @@ -238,8 +267,8 @@ def _drop_constraint(constraint, autogen_context): text = template % { 'prefix': _alembic_autogenerate_prefix(autogen_context), 'name': _render_gen_name(autogen_context, constraint.name), - 'table_name': constraint.table.name, - 'schema': (", schema='%s'" % constraint.table.schema) + 'table_name': _ident(constraint.table.name), + 'schema': (", schema='%s'" % _ident(constraint.table.schema)) if constraint.table.schema else '', } return text @@ -273,9 +302,9 @@ def _drop_column(schema, tname, column, autogen_context): text = template % { "prefix": _alembic_autogenerate_prefix(autogen_context), - "tname": tname, - "cname": column.name, - "schema": schema + "tname": _ident(tname), + "cname": _ident(column.name), + "schema": _ident(schema) } return text @@ -382,7 +411,7 @@ def _render_column(column, autogen_context): # TODO: for non-ascii colname, assign a "key" return "%(prefix)sColumn(%(name)r, %(type)s, %(kw)s)" % { 'prefix': _sqlalchemy_autogenerate_prefix(autogen_context), - 'name': column.name, + 'name': _ident(column.name), 'type': _repr_type(column.type, autogen_context), 'kw': ", ".join(["%s=%s" % (kwname, val) for kwname, val in opts]) } @@ -494,7 +523,7 @@ def _render_foreign_key(constraint, autogen_context): "[%(refcols)s], %(args)s)" % { "prefix": _sqlalchemy_autogenerate_prefix(autogen_context), "cols": ", ".join( - "'%s'" % f.parent.key for f in constraint.elements), + "%r" % f.parent.key for f in constraint.elements), "refcols": ", ".join(repr(_fk_colspec(f, apply_metadata_schema)) for f in constraint.elements), "args": ", ".join( @@ -522,7 +551,8 @@ def _render_check_constraint(constraint, autogen_context): opts.append( ( "name", - repr(_render_gen_name(autogen_context, constraint.name)) + repr( + _render_gen_name(autogen_context, constraint.name)) ) ) return "%(prefix)sCheckConstraint(%(sqltext)s%(opts)s)" % { diff --git a/alembic/compat.py b/alembic/compat.py index c7d0dce..240ee75 100644 --- a/alembic/compat.py +++ b/alembic/compat.py @@ -30,6 +30,9 @@ if py3k: def u(s): return s + def ue(s): + return s + else: import __builtin__ as compat_builtins string_types = basestring, @@ -40,6 +43,9 @@ else: def u(s): return unicode(s, "utf-8") + def ue(s): + return unicode(s, "unicode_escape") + if py3k: from configparser import ConfigParser as SafeConfigParser import configparser @@ -96,6 +102,31 @@ def with_metaclass(meta, base=object): return meta("%sBase" % meta.__name__, (base,), {}) ################################################ +if py3k: + def reraise(tp, value, tb=None, cause=None): + if cause is not None: + value.__cause__ = cause + if value.__traceback__ is not tb: + raise value.with_traceback(tb) + raise value + + def raise_from_cause(exception, exc_info=None): + if exc_info is None: + exc_info = sys.exc_info() + exc_type, exc_value, exc_tb = exc_info + reraise(type(exception), exception, tb=exc_tb, cause=exc_value) +else: + exec("def reraise(tp, value, tb=None, cause=None):\n" + " raise tp, value, tb\n") + + def raise_from_cause(exception, exc_info=None): + # not as nice as that of Py3K, but at least preserv + # the code line where the issue occurred + if exc_info is None: + exc_info = sys.exc_info() + exc_type, exc_value, exc_tb = exc_info + reraise(type(exception), exception, tb=exc_tb) + if py3k: def reraise(tp, value, tb=None, cause=None): diff --git a/alembic/testing/assertions.py b/alembic/testing/assertions.py index d31057a..f5e992e 100644 --- a/alembic/testing/assertions.py +++ b/alembic/testing/assertions.py @@ -1,7 +1,7 @@ import re from alembic import util from sqlalchemy.engine import default -from alembic.compat import text_type +from alembic.compat import text_type, py3k if not util.sqla_094: def eq_(a, b, msg=None): @@ -45,6 +45,14 @@ def eq_ignore_whitespace(a, b, msg=None): a = re.sub(r' {2,}', " ", a) b = re.sub(r'^\s+?|\n', "", b) b = re.sub(r' {2,}', " ", b) + + # convert for unicode string rendering, + # using special escape character "!U" + if py3k: + b = re.sub(r'!U', '', b) + else: + b = re.sub(r'!U', 'u', b) + assert a == b, msg or "%r != %r" % (a, b) diff --git a/alembic/testing/exclusions.py b/alembic/testing/exclusions.py index a64fe35..88df9fc 100644 --- a/alembic/testing/exclusions.py +++ b/alembic/testing/exclusions.py @@ -137,7 +137,7 @@ class compound(object): name, fail._as_string(config), str(ex)))) break else: - raise ex + compat.raise_from_cause(ex) def _expect_success(self, config, name='block'): if not self.fails: diff --git a/docs/build/changelog.rst b/docs/build/changelog.rst index fb9990f..cc1f4c4 100644 --- a/docs/build/changelog.rst +++ b/docs/build/changelog.rst @@ -14,6 +14,19 @@ Changelog alone by default; use ``--verbose`` to get at additional output. .. change:: + :tags: bug, autogenerate + :tickets: 243 + + Fixed a variety of issues surrounding rendering of Python code that + contains unicode literals. The first is that the "quoted_name" construct + that SQLAlchemy uses to represent table and column names as well + as schema names does not ``repr()`` correctly on Py2K when the value + contains unicode characters; therefore an explicit stringification is + added to these. Additionally, SQL expressions such as server defaults + were not being generated in a unicode-safe fashion leading to decode + errors if server defaults contained non-ascii characters. + + .. change:: :tags: bug, operations :tickets: 174 :pullreq: bitbucket:29 diff --git a/tests/test_autogen_render.py b/tests/test_autogen_render.py index 648b3f7..ddd108e 100644 --- a/tests/test_autogen_render.py +++ b/tests/test_autogen_render.py @@ -95,14 +95,14 @@ class AutogenRenderTest(TestBase): autogenerate.render._add_index(idx, autogen_context), """op.create_index('foo_idx', 't', \ ['x', 'y'], unique=False, """ - """postgresql_where=sa.text("t.y = 'something'"))""" + """postgresql_where=sa.text(!U"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=sa.text('t.y = %(y_1)s'))""" + """postgresql_where=sa.text(!U't.y = %(y_1)s'))""" ) @config.requirements.fail_before_sqla_080 @@ -117,7 +117,7 @@ unique=False, """ eq_ignore_whitespace( autogenerate.render._add_index(idx, self.autogen_context), "op.create_index('test_lower_code_idx', 'test', " - "[sa.text('lower(test.code)')], unique=False)" + "[sa.text(!U'lower(test.code)')], unique=False)" ) @config.requirements.fail_before_sqla_080 @@ -132,7 +132,7 @@ unique=False, """ eq_ignore_whitespace( autogenerate.render._add_index(idx, self.autogen_context), "op.create_index('test_lower_code_idx', 'test', " - "[sa.text('CAST(test.code AS CHAR)')], unique=False)" + "[sa.text(!U'CAST(test.code AS CHAR)')], unique=False)" ) @config.requirements.fail_before_sqla_080 @@ -147,7 +147,7 @@ unique=False, """ eq_ignore_whitespace( autogenerate.render._add_index(idx, self.autogen_context), "op.create_index('test_desc_code_idx', 'test', " - "[sa.text('test.code DESC')], unique=False)" + "[sa.text(!U'test.code DESC')], unique=False)" ) def test_drop_index(self): @@ -300,6 +300,32 @@ unique=False, """ ")" ) + def test_render_table_w_unicode_name(self): + m = MetaData() + t = Table(compat.ue('\u0411\u0435\u0437'), m, + Column('id', Integer, primary_key=True), + ) + eq_ignore_whitespace( + autogenerate.render._add_table(t, self.autogen_context), + "op.create_table(%r," + "sa.Column('id', sa.Integer(), nullable=False)," + "sa.PrimaryKeyConstraint('id'))" % compat.ue('\u0411\u0435\u0437') + ) + + def test_render_table_w_unicode_schema(self): + m = MetaData() + t = Table('test', m, + Column('id', Integer, primary_key=True), + schema=compat.ue('\u0411\u0435\u0437') + ) + eq_ignore_whitespace( + autogenerate.render._add_table(t, self.autogen_context), + "op.create_table('test'," + "sa.Column('id', sa.Integer(), nullable=False)," + "sa.PrimaryKeyConstraint('id')," + "schema=%r)" % compat.ue('\u0411\u0435\u0437') + ) + @patch("alembic.autogenerate.render.MAX_PYTHON_ARGS", 3) def test_render_table_max_cols(self): m = MetaData() @@ -359,7 +385,8 @@ unique=False, """ eq_ignore_whitespace( re.sub( r"u'", "'", - autogenerate.render._add_table(t, self.autogen_context)), + autogenerate.render._add_table(t, self.autogen_context) + ), "op.create_table('test'," "sa.Column('id', sa.Integer(), nullable=False)," "sa.Column('q', sa.Integer(), nullable=True)," @@ -404,14 +431,14 @@ unique=False, """ ) def test_render_drop_table(self): - eq_( + eq_ignore_whitespace( autogenerate.render._drop_table(Table("sometable", MetaData()), self.autogen_context), "op.drop_table('sometable')" ) def test_render_drop_table_w_schema(self): - eq_( + eq_ignore_whitespace( autogenerate.render._drop_table( Table("sometable", MetaData(), schema='foo'), self.autogen_context), @@ -435,7 +462,8 @@ unique=False, """ eq_ignore_whitespace( autogenerate.render._add_table(t1, self.autogen_context), - "op.create_table('t1',sa.Column('x', sa.Integer(), nullable=True))" + "op.create_table('t1'," + "sa.Column('x', sa.Integer(), nullable=True))" ) eq_ignore_whitespace( @@ -446,7 +474,7 @@ unique=False, """ ) def test_render_add_column(self): - eq_( + eq_ignore_whitespace( autogenerate.render._add_column( None, "foo", Column("x", Integer, server_default="5"), self.autogen_context), @@ -455,7 +483,7 @@ unique=False, """ ) def test_render_add_column_w_schema(self): - eq_( + eq_ignore_whitespace( autogenerate.render._add_column( "foo", "bar", Column("x", Integer, server_default="5"), self.autogen_context), @@ -464,7 +492,7 @@ unique=False, """ ) def test_render_drop_column(self): - eq_( + eq_ignore_whitespace( autogenerate.render._drop_column( None, "foo", Column("x", Integer, server_default="5"), self.autogen_context), @@ -473,7 +501,7 @@ unique=False, """ ) def test_render_drop_column_w_schema(self): - eq_( + eq_ignore_whitespace( autogenerate.render._drop_column( "foo", "bar", Column("x", Integer, server_default="5"), self.autogen_context), @@ -489,6 +517,24 @@ unique=False, """ '"nextval(\'group_to_perm_group_to_perm_id_seq\'::regclass)"' ) + def test_render_unicode_server_default(self): + default = compat.ue( + '\u0411\u0435\u0437 ' + '\u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f' + ) + + c = Column( + 'x', Unicode, + server_default=text(default) + ) + + eq_ignore_whitespace( + autogenerate.render._render_server_default( + c.server_default, self.autogen_context + ), + "sa.text(%r)" % default + ) + def test_render_col_with_server_default(self): c = Column('updated_at', TIMESTAMP(), server_default='TIMEZONE("utc", CURRENT_TIMESTAMP)', @@ -496,7 +542,7 @@ unique=False, """ result = autogenerate.render._render_column( c, self.autogen_context ) - eq_( + eq_ignore_whitespace( result, 'sa.Column(\'updated_at\', sa.TIMESTAMP(), ' 'server_default=\'TIMEZONE("utc", CURRENT_TIMESTAMP)\', ' @@ -509,7 +555,7 @@ unique=False, """ result = autogenerate.render._render_column( c, self.autogen_context ) - eq_( + eq_ignore_whitespace( result, 'sa.Column(\'some_key\', sa.Integer(), ' 'autoincrement=False, ' @@ -542,10 +588,11 @@ unique=False, """ result = autogenerate.render._add_table( t, autogen_context ) - eq_( - result, """sa.create_table('t', -col(x), -render:primary_key\n)""" + eq_ignore_whitespace( + result, + "sa.create_table('t'," + "col(x)," + "render:primary_key)" ) def test_render_modify_type(self): @@ -601,6 +648,9 @@ render:primary_key\n)""" if not util.sqla_08: t1.append_constraint(fk) + # SQLA 0.9 generates a u'' here for remote cols while 0.8 does not, + # so just whack out "'u" here from the generated + eq_ignore_whitespace( re.sub( r"u'", "'", @@ -628,7 +678,8 @@ render:primary_key\n)""" re.sub( r"u'", "'", autogenerate.render._render_constraint( - fk, self.autogen_context)), + fk, self.autogen_context), + ), "sa.ForeignKeyConstraint(['c'], ['t2.c_rem'], deferrable=True)" ) @@ -639,7 +690,8 @@ render:primary_key\n)""" re.sub( r"u'", "'", autogenerate.render._render_constraint( - fk, self.autogen_context)), + fk, self.autogen_context) + ), "sa.ForeignKeyConstraint(['c'], ['t2.c_rem'], initially='XYZ')" ) @@ -673,7 +725,8 @@ render:primary_key\n)""" re.sub( r"u'", "'", autogenerate.render._render_constraint( - fk, self.autogen_context)), + fk, self.autogen_context) + ), "sa.ForeignKeyConstraint(['c'], ['foo.t2.c_rem'], " "onupdate='CASCADE')" ) @@ -684,7 +737,7 @@ render:primary_key\n)""" CheckConstraint("im a constraint", name='cc1'), self.autogen_context ), - "sa.CheckConstraint('im a constraint', name='cc1')" + "sa.CheckConstraint(!U'im a constraint', name='cc1')" ) def test_render_check_constraint_sqlexpr(self): @@ -696,7 +749,7 @@ render:primary_key\n)""" CheckConstraint(and_(c > five, c < ten)), self.autogen_context ), - "sa.CheckConstraint('c > 5 AND c < 10')" + "sa.CheckConstraint(!U'c > 5 AND c < 10')" ) @config.requirements.fail_before_sqla_080 @@ -707,7 +760,7 @@ render:primary_key\n)""" CheckConstraint(and_(c > 5, c < 10)), self.autogen_context ), - "sa.CheckConstraint('c > 5 AND c < 10')" + "sa.CheckConstraint(!U'c > 5 AND c < 10')" ) def test_render_unique_constraint_opts(self): @@ -721,6 +774,21 @@ render:primary_key\n)""" "sa.UniqueConstraint('c', deferrable='XYZ', name='uq_1')" ) + def test_add_unique_constraint_unicode_schema(self): + m = MetaData() + t = Table( + 't', m, Column('c', Integer), + schema=compat.ue('\u0411\u0435\u0437') + ) + eq_ignore_whitespace( + autogenerate.render._add_unique_constraint( + UniqueConstraint(t.c.c), + self.autogen_context + ), + "op.create_unique_constraint(None, 't', ['c'], " + "schema=%r)" % compat.ue('\u0411\u0435\u0437') + ) + def test_render_modify_nullable_w_default(self): eq_ignore_whitespace( autogenerate.render._modify_col( @@ -839,10 +907,10 @@ render:primary_key\n)""" result = autogenerate.render._render_column( c, self.autogen_context ) - eq_( + eq_ignore_whitespace( result, 'sa.Column(\'updated_at\', sa.TIMESTAMP(), ' - 'server_default=sa.text(\'now()\'), ' + 'server_default=sa.text(!U\'now()\'), ' 'nullable=False)' ) @@ -861,10 +929,10 @@ render:primary_key\n)""" result = autogenerate.render._render_column( c, autogen_context, ) - eq_( + eq_ignore_whitespace( result, 'sa.Column(\'updated_at\', sa.Boolean(), ' - 'server_default=sa.text(\'false\'), ' + 'server_default=sa.text(!U\'false\'), ' 'nullable=False)' ) @@ -886,10 +954,10 @@ render:primary_key\n)""" result = autogenerate.render._render_column( c, autogen_context ) - eq_( + eq_ignore_whitespace( result, 'sa.Column(\'updated_at\', sa.Boolean(), ' - 'server_default=sa.text(\'0\'), ' + 'server_default=sa.text(!U\'0\'), ' 'nullable=False)' ) @@ -901,10 +969,10 @@ render:primary_key\n)""" result = autogenerate.render._render_column( c, self.autogen_context ) - eq_( + eq_ignore_whitespace( result, 'sa.Column(\'updated_at\', sa.TIMESTAMP(), ' - 'server_default=sa.text(\'now()\'), ' + 'server_default=sa.text(!U\'now()\'), ' 'nullable=False)' ) @@ -931,11 +999,10 @@ render:primary_key\n)""" nullable=True), "op.alter_column('sometable', 'somecolumn', " "existing_type=sa.Integer(), nullable=True, " - "existing_server_default=sa.text('5'))" + "existing_server_default=sa.text(!U'5'))" ) - class RenderNamingConventionTest(TestBase): __requires__ = ('sqlalchemy_094',) @@ -1059,7 +1126,7 @@ class RenderNamingConventionTest(TestBase): eq_ignore_whitespace( autogenerate.render._add_table(t, self.autogen_context), "op.create_table('t',sa.Column('c', sa.Integer(), nullable=True)," - "sa.CheckConstraint('c > 5', name=op.f('ck_ct_t')))" + "sa.CheckConstraint(!U'c > 5', name=op.f('ck_ct_t')))" ) def test_inline_fk(self): @@ -1092,6 +1159,6 @@ class RenderNamingConventionTest(TestBase): ck, self.autogen_context ), - "sa.CheckConstraint('im a constraint', name=op.f('ck_t_cc1'))" + "sa.CheckConstraint(!U'im a constraint', name=op.f('ck_t_cc1'))" ) |