Hello,

first and foremost: thank you for SQLAlchemy and Alembic. I've worked with 
a lot of ORMs, but only with these two I feel very comfortable and I'm 
doing a lot of crazy stuff with it.

The current problem that I have: I'm currently creating a lot of tables 
with a lot of mixins, as most of them have e.g. an id-column or columns for 
created_at-dates etc. However it seems that I can't control the order of 
the columns, resulting in e.g. the primary-key-id-column to show up in the 
middle of the other columns or the created_at-column at the beginning and 
the created_by-column at the end, especially when I autogenerate the 
versioning scripts. But alembic has also a method in this case (as always 
;-)). So I created a Rewriter-method for the CreateTableOps in the env.py-file, 
re-order the columns in the correct way and reassign this ordered list of 
columns to op.columns. Unfortunately this doesn't work. Somehow it either 
uses whatever is already the to_table()-method (?) or ... something else. 
So I tried to create a new operation in the rewriter with the ordered list 
and returned this operation instead. But then I get an the error: 
sqlalchemy.exc.ArgumentError: 
Column object 'id' already assigned to Table 'user'.

The code I'm using is the following:

from operator import itemgetter
from alembic.autogenerate import rewriter
from alembic.operations.ops import CreateTableOp
from sqlalchemy.sql.schema import Column


writer = rewriter.Rewriter()


@writer.rewriter(CreateTableOp)
def order_columns(context, revision, op):
    """Reorder the columns before creating a table."""
    preordered = []
    for col in op.columns:
        k = 0  # key used for ordering later on
        if not isinstance(col, Column):
            k = 99  # All constraints or indexes should stay at the end of 
the definition
        elif col.primary_key and col.name=='id':
            k = 1
        # + a lot of other ordering constraints for other columns
        else:
            k= 2                     # All non-id-columns
        preordered.append((k, col))  # Creating my ordered list

    # Now sorting the list and extracting only the column-objects.
    # This list is indeed correctly sorted, just what I want
    ordered_column_list = [itm[1] for itm in sorted(preordered, key=
itemgetter(0))]

    # Creating a new operation and returning it is not working, as it 
results in an error:
    # Returning: ArgumentError: Column object '...' already assigned to 
Table '...'
    # new_op = CreateTableOp(op.table_name, ordered_column_list, 
schema=op.schema)
    # return new_op

    # Reassigning the ordered column list is not working either, it seems 
to be ignored:
    op.columns = ordered_column_list
    return op

[...]

def run_migrations_online():
[...]
    with connectable.connect() as connection:
        context.configure(
            [...]
            process_revision_directives=writer
        )
[...]


The problem is similar to Altering the behavior of AddColumn 
<https://groups.google.com/forum/#!searchin/sqlalchemy-alembic/order|sort:date/sqlalchemy-alembic/izYq2EMYotI/gMISQpjkAwAJ>,
 
but I need to order multiple columns. The ordering works perfectly fine, 
the rewriter is also invoked (tested it e.g. by returning [] instead or 
debugging), just the reordered list of columns is then totally ignored.

Any hint to point me in the right direction of what I'm doing wrong or any 
other possibility to do the reordering?

Thank you in advance and thanks again

David

-- 
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.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy-alembic/ef49db6c-420c-49ec-a708-86ad5d874fc1%40googlegroups.com.

Reply via email to