Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Flask-migrate and changing column type

Tags:

I am trying to learn some Flask and I am using Flask-Migrate 1.6.0

So I made a model which looks like this

class Download(db.Model):      __tablename__ = "downloads"      id = db.Column(db.Integer, autoincrement=True, primary_key=True)     filename = db.Column(db.String, nullable=False)     size = db.Column(db.Integer, nullable=False)     location = db.Column(db.String, nullable=False)     season = db.Column(db.Integer, nullable=False)     download_timestamp = db.Column(db.DateTime, nullable=False)      show_id = db.Column(db.Integer, ForeignKey("shows.id"))      def __init__(self,filename,size,location,timestamp,season):         self.filename = filename         self.size = size         self.location = location         self.download_timestamp = timestamp         self.season = season      def __repr__(self):         return '<File {}'.format(self.filename) 

I have then changed it to the exact same thing except for this line :

size = db.Column(db.BigInteger, nullable=False) 

When I run my

manager.py db migrate 

command it doesn't detect the change in the column type. And I have read up on it and I know it should pick it up when I change my env.py and add the compare_type=True variable. But I did this to no avail, the method looks like this right now

def run_migrations_online():     """Run migrations in 'online' mode.      In this scenario we need to create an Engine     and associate a connection with the context.      """      # this callback is used to prevent an auto-migration from being generated     # when there are no changes to the schema     # reference: http://alembic.readthedocs.org/en/latest/cookbook.html     def process_revision_directives(context, revision, directives):         if getattr(config.cmd_opts, 'autogenerate', False):             script = directives[0]             if script.upgrade_ops.is_empty():                 directives[:] = []                 logger.info('No changes in schema detected.')      engine = engine_from_config(config.get_section(config.config_ini_section),                                 prefix='sqlalchemy.',                                 poolclass=pool.NullPool)      connection = engine.connect()     context.configure(connection=connection,                       target_metadata=target_metadata,                       compare_type=True,                       process_revision_directives=process_revision_directives,                       **current_app.extensions['migrate'].configure_args)      try:         with context.begin_transaction():             context.run_migrations()     finally:         connection.close() 

Ok so my questions are:

Did I do something wrong in changing the env.py file?

If I didn't and it still doesn't pick up on it how do I exactly manually make the next migration revision? Because the revisions in my migrate folder have names like below and stuff in it like this

# revision identifiers, used by Alembic. revision = '7e9f264b0f' down_revision = '2e59d536f50' 

I guess I could just copy one, make up a name .. but would the next one that is picked up by flask migrate recognize it? So yeah.. what is the correct way of handling it without too much iffy hacking?

like image 962
Thustra Avatar asked Nov 26 '15 17:11

Thustra


People also ask

What is flask migrate?

Flask migrate is defined as an extension that is used in the Flask application for handling database migrations for SQLAlchemy using Alembic. This module enables developers to quickly set up and starts the database schema migrations.

How do I sync a flask database with another system?

To sync the database in another system just refresh the migrations folder from source control and run the upgrade command. Note that the application script must be set in the FLASK_APP environment variable for all the above commands to work, as required by the flask command line script.

What is the flask-migrate extension?

Flask-Migrate is an extension that configures Alembic in the proper way to work with your Flask and Flask-SQLAlchemy application. In terms of the actual database migrations, everything is handled by Alembic so you get exactly the same functionality. This is an example application that handles database migrations through Flask-Migrate:

How to use multiple configuration callbacks in flask-migrate?

Using decorator allows usage of multiple configuration callbacks and the order in which the callbacks are invoked are undetermined. Once the configuration piece is sorted, it would be time for binding the databases. The installation of the SQL alchemy module provides features to allow Flask-migrate to track migrations to multiple databases.


2 Answers

Just need to add compare_type=True in the Migrate constructor

from flask_migrate import Migrate migrate = Migrate(compare_type=True)  app = Flask(__name__) migrate.init_app(app) 
like image 185
enpi_ Avatar answered Nov 01 '22 06:11

enpi_


Update:

As expected, this answer is now out of date, please see https://stackoverflow.com/a/52181159/428907 for a real fix!

Original Answer:

Alembic does not recognize things like column type changes when auto-generating revisions by default. When making these more granular changes, you will need to hand-modify the migration to include these changes

e.g., in your migration file

from alembic import op import sqlalchemy as sa def upgrade():     # ...     op.alter_column('downloads', 'size', existing_type=sa.Integer(), type_=sa.BigInteger()) def downgrade():     # ...     op.alter_column('downloads', 'size', existing_type=sa.BigInteger(), type_=sa.Integer()) 

For details on the operations, see the operation reference

You can turn on detection of type changes by modifying your env.py and alembic.ini, as seen here

like image 39
KageUrufu Avatar answered Nov 01 '22 06:11

KageUrufu