4

My database is MySQL. I use SqlAlchemy ORM to define and access it. I use Alembic for migrations. I have a model with a field that used to contain just English text (Ascii/latin-1). Now, this field needs to contain Unicode text. In order to convert my model to support Unicode for MySQL I need to add the following class level attribute: mysql_character_set = 'utf8'

class MyModel(Base):
    __tablename__ = 'mymodel'
    mysql_character_set = 'utf8'

    id = Column(Integer, primary_key=True)
    name = Column(String(64), unique=True, nullable=False)

So far so good. I want to add this attribute as part of an Alembic migration script. I normally use Alembic's excellent auto-generate command:

alembic revision --autogenerate

The problem is that this command doesn't capture every model change and in particular not the addition of the mysql_character_set attribute.

How do I add this attribute manually to the alembic migration script?

Eugene Yarmash
  • 131,677
  • 37
  • 301
  • 358
Pyramid Newbie
  • 5,917
  • 3
  • 22
  • 27
  • canyou try, am not sure. create_engine("mysql+mysqldb://user:pass@host/dbname?charset=utf8&use_unicode=0") – Jisson Dec 10 '14 at 16:22

2 Answers2

4

I did it like this:

from alembic import op
import sqlalchemy as sa


def upgrade():
    conn = op.get_bind()
    conn.execute(sa.sql.text('ALTER table my_table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci'))
radtek
  • 30,748
  • 10
  • 135
  • 106
Sjoerd
  • 71,634
  • 16
  • 123
  • 171
1

You should use the utf8mb4 character set, as utf8 (aka utf8mb3) is broken.

To change the default character set for a table and convert all character columns (CHAR, VARCHAR, TEXT) to the new character set, you can use ALTER TABLE in a migration (but see the docs for possible side effects):

from alembic import op


def upgrade():
   op.execute(
       'ALTER TABLE mytable CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci'
   )

def downgrade():
    op.execute(
        'ALTER TABLE mytable CONVERT TO CHARACTER SET latin1 COLLATE latin1_swedish_ci'
    )
Eugene Yarmash
  • 131,677
  • 37
  • 301
  • 358