pythonsqlalchemyalembicflask-migratesqlalchemy-migrate

How to specify a full text search index (MySQL) in an Alembic migration?


I'm using Flask-Migrate for a project in which the target database is MySQL-compatible Aurora.

I added a full-text index to a model using Menzhuo's SQLAlchemy fulltext search module:

class Post(db.Model, FullText, Serializable):
    __tablename__ = 'post'
    __fulltext_columns__ = ('description', 'text')
    id = db.Column(db.String(10), primary_key=True)
    description = db.Column(db.String(256))
    .
    .
    .

Now when I used Flask-Migrate to generate the migration, the full text index was not picked up automatically. I am well aware of the fact that Flask-Migrate does not pick everything up, and that you have to add a few things by hand to the migration scripts.

For example, I know how to manually insert lines such as

op.add_column(...)
op.create_unique_constraint(...)
op.create_index(...)

inside of the upgrade method in the generated migration. However, when I looked at the create_index documentation for Alembic I do not see any support for creating a full text index. I see the unique parameter for unique indexes, but nothing for the full text index.

So am I missing the way to do this directly in Alembic (perhaps using SQLAlchemy commands)? Or would I have to write straight SQL? I would hate to have to do the latter, and I've never done that before. If that is necessary, how does that work?


Solution

  • From the Alembic documentation on create_index() we find that

    • **kw – Additional keyword arguments not mentioned above are dialect specific, and passed in the form <dialectname>_<argname>. See the documentation regarding an individual dialect at Dialects for detail on documented arguments.

    and then in MySQL dialect documentation under "Index Prefixes":

    MySQL storage engines permit you to specify an index prefix when creating an index. SQLAlchemy provides this feature via the mysql_prefix parameter on Index:

    Index('my_index', my_table.c.data, mysql_prefix='FULLTEXT')
    

    Given the above your Alembic migration should define the index like so:

    op.create_index(..., mysql_prefix='FULLTEXT')