Issues

Issue #31 resolved

autogenerate, could generate invalid python code

Marcin Kuzminski
created an issue

I'm testing out autogenerate and got something like that in the proposed script:

def downgrade():
    ### commands auto generated by Alembic - please adjust! ###
    op.drop_table('users_group_repo_group_to_perm')
    op.drop_table('notifications')
    op.drop_table('user_to_notification')
    op.drop_table('user_repo_group_to_perm')
    op.drop_table('changeset_comments')
    op.create_table(u'group_to_perm',
    sa.Column(u'group_to_perm_id', sa.INTEGER(), server_default='nextval('group_to_perm_group_to_perm_id_seq'::regclass)', nullable=False), #<-- PROBLEM !
    sa.Column(u'user_id', sa.INTEGER(), nullable=False),
    sa.Column(u'permission_id', sa.INTEGER(), nullable=False),
    sa.Column(u'group_id', sa.INTEGER(), nullable=False),
    sa.ForeignKeyConstraint(['group_id'], [u'groups.group_id'], name=u'group_to_perm_group_id_fkey'),
    sa.ForeignKeyConstraint(['permission_id'], [u'permissions.permission_id'], name=u'group_to_perm_permission_id_fkey'),
    sa.ForeignKeyConstraint(['user_id'], [u'users.user_id'], name=u'group_to_perm_user_id_fkey'),
    sa.PrimaryKeyConstraint(u'group_to_perm_id', name=u'group_to_perm_pkey')
    )
    op.alter_column(u'user_logs', u'repository_id', 
               existing_type=sa.INTEGER(), 
               nullable=False)

i think it can be patched with

diff --git a/alembic/autogenerate.py b/alembic/autogenerate.py
--- a/alembic/autogenerate.py
+++ b/alembic/autogenerate.py
@@ -401,17 +401,17 @@ def _render_server_default(default, auto
             default = default.arg
         else:
             default = str(default.arg.compile(dialect=autogen_context['dialect']))
     if isinstance(default, basestring):
         # TODO: this is just a hack to get 
         # tests to pass until we figure out
         # WTF sqlite is doing
         default = re.sub(r"^'|'$", "", default)
-        return "'%s'" % default
+        return "'''%s'''" % default
     else:
         return None

 def _repr_type(prefix, type_, autogen_context):
     mod = type(type_).__module__
     imports = autogen_context.get('imports', None)
     if mod.startswith("sqlalchemy.dialects"):
         dname = re.match(r"sqlalchemy\.dialects\.(\w+)", mod).group(1)

Comments (6)

  1. Marcin Kuzminski reporter

    repr would generate it as server_default='"nextval(\'group_to_perm_group_to_perm_id_seq\'::regclass)"' I prefer the triple-quote solution due to it looks cleaner for me. What do you think ?

  2. Anonymous

    Wouldn't triple quotes still break if the suggested value also contained three quotes in a row? in that case, repr() would always work.

  3. grault

    My first attempt with 0.3.4, just today, threw this same problem too. His triple-quote fix worked, and so did repr(). Seems to me Anon's suggestion outweighs the clean looks of the triple-quoted solution.

    First ever trial of Alembic and I'm impressed how quickly I was able to put together a working migration. Thanks.

  4. Log in to comment