more straightforward would be a pull request that adds "mysql_after"
keyword to both op.add_column() and op.modify_column().

On Fri, Jul 7, 2017 at 1:33 AM,  <tjhn...@gmail.com> wrote:
>
>
> On Tuesday, August 27, 2013 at 9:31:29 AM UTC-5, Michael Bayer wrote:
>>
>>
>> On Aug 26, 2013, at 11:49 PM, Samer Atiani <sat...@gmail.com> wrote:
>>
>> Hello,
>>
>> All my tables have create_date and update_date columns in them, and I like
>> to keep these columns as the last two columns in any table for convention
>> reasons. However, when you use alembic autogenerate to generate schema
>> migrations to add columns, the columns are always added to the end of the
>> table. With time, the create_date and update_date columns in my tables will
>> end up being in the middle of the column list in my MySQL database.
>>
>> So I was trying to alter this behavior by making alembic use MySQL's
>> "ALTER TABLE x ADD COLUMN y AFTER z" feature to always try to add columns
>> before create_date or update_date. The only way I could find out how is to
>> override the visit_add_column method after EnvironmentContext configuration.
>> I achieved this by changing the "run_migrations_online()" method in
>> alembic/env.py so that it looks like:
>>
>>
>> However, this feels quite brittle and is probably touching internal stuff
>> that it shouldn't touch. My question to you is: is there a better way to
>> achieve this? I looked at SQLAlchemy Core Events, but I couldn't find an
>> event that could correspond to adding columns, nor is the alembic code
>> firing any events I could see when it add columns (unlike, for example, when
>> it emits a CREATE TABLE statements).
>>
>>
>>
>> AddColumn is a SQL expression element so the standard way we want to
>> override those is to use @compiles
>> (http://docs.sqlalchemy.org/en/rel_0_8/core/compiler.html#changing-the-default-compilation-of-existing-constructs).
>> As you might have noticed, Alembic is already using that system internally
>> in order to provide compile rules for constructs.   So we want to override
>> that, however the roadblock is that the @compiles system currently doesn't
>> have a nice way of letting us override the @compiles of an existing
>> @compiles (should be added as a feature).  So there's a slight bit of
>> internals we need to get at Alembic's already present @compiles rule for
>> now, but the rest is straightforward:
>>
>> from sqlalchemy.ext.compiler import compiles
>> from alembic.ddl.base import AddColumn
>>
>> # ideally, the @compiles system would have some way of getting
>> # us the "existing" @compiles decorator, so this part is the
>> # hack
>> specs = AddColumn.__dict__.get('_compiler_dispatcher').specs
>> existing_dispatch = specs.get('mysql', specs['default'])
>>
>> @compiles(AddColumn, "mysql")
>> def add_column(element, compiler, **kw):
>>     text = existing_dispatch(element, compiler, **kw)
>>     if "after" in element.column.info:
>>         text += " AFTER %s" % element.column.info['after']
>>     return text
>>
>> from sqlalchemy import Column, Integer
>> from alembic.migration import MigrationContext
>> from alembic.operations import Operations
>>
>> ctx = MigrationContext.configure(dialect_name="mysql", opts={"as_sql":
>> True})
>> op = Operations(ctx)
>>
>> op.add_column("t", Column('y', Integer))
>>
>> op.add_column("t", Column('x', Integer, info={"after": "y"}))
>
>
>
> I'm interested in applying a similar solution to handle alter columns.
>
> The problem I'm seeing is that  MySQLImpl.alter_column() does not pass *kw
> to MySQLChangeColumn or  MySQLModifyColumn. So there doesn't seem to be a
> simple way that I can write a @compiles(MySQLChangeColumn, 'mysql')
> decorated function, and the interface would have to be something like
> element.info  instead of element.column.info too.   Also, can you explain
> why I have to use MySQLChangeColumn/MySQLModifyColumn instead of AlterColumn
> in the @compiles decorator?
>
> Would it be possible to get support for this into alembic proper?  I can get
> it to work, but I have to monkey patch MySQLImpl.
>
> --
> You received this message because you are subscribed to the Google Groups
> "sqlalchemy-alembic" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sqlalchemy-alembic+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy-alembic" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy-alembic+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to