Flask-migrate does not work along with Flask-fixtures

33 views Asked by At

I am quite new to Flask and Postgres, so hopefully my explanation and code make sense.

I am trying to run a postgres docker container for the test with some test data loaded into it. I need to use Flask-Migrate and Flask-Fixtures in one function.

Flask-Migrate for upgrading the database with table names, schemas, relations and etc.

Flask-Fixtures for loading test data into the tables from yaml file.

When I use postgres db with pre-created tables (migrations, schemas etc) and try to load the data with flask_fixtures everything works properly, all the data is loaded into the tables (code below).

def _load_db_fixtures(self, input_db_fixture_path, db_migrations_directory):
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://test:test@postgres:5432/test"
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    db = SQLAlchemy(app)
    db.metadata.reflect(bind=db.engine)

    def _reload_fixture(fixture_file):
        """Reload fixtures."""
        import flask_fixtures
        import yaml
        from yaml import SafeLoader
        meta = db.metadata
        session = db.session
        with session.begin(nested=True), open(fixture_file, mode='r') as fp:
            flask_fixtures.load_fixtures(db, yaml.load(fp, SafeLoader))
        return "Reloaded"
   _reload_fixture(input_db_fixture_path) 

However, my goal is to use empty postgres container so I need to use flask_migrate to upgrade migrations (migrations directory already exists in the application, with alembic file and etc). So the problem is that flask_fixtures stops working properly when I add flask_migrate commands. Giving an integrity error with null value insertion attempt (code below)****.

sqlalchemy.exc.IntegrityError: (psycopg2.errors.NotNullViolation) null value in column "id" of relation "accounts" violates not-null

def _load_db_fixtures(self, input_db_fixture_path, db_migrations_directory):
    app = Flask(__name__)
    app.config['SQLALCHEMY_DATABASE_URI'] = "postgresql://test:test@postgres:5432/test"
    app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
    db = SQLAlchemy(app)
    db.metadata.reflect(bind=db.engine)
    migrate = Migrate(app, db)
    with app.app_context():
        flask_migrate.upgrade(directory = db_migrations_directory)
    
    def _reload_fixture(fixture_file):
        """Reload fixtures."""
        import flask_fixtures
        import yaml
        from yaml import SafeLoader
        meta = db.metadata
        session = db.session
        with session.begin(nested=True), open(fixture_file, mode='r') as fp:
            flask_fixtures.load_fixtures(db, yaml.load(fp, SafeLoader))
        return "Reloaded"
   _reload_fixture(input_db_fixture_path) 

I have noticed that the load_fixture (loading data into the tables) works fine again if I run the code second time (after migration part is done and loading data raises an error) with flask_migrate part commented

# migrate = Migrate(app, db)

# with app.app_context():
#    flask_migrate.upgrade(directory = db_migrations_directory)  

So I guess the problem is with Migrate(app, db) part, somehow making db unavailable for the loading.

Please give me a shout if you see an obvious issue and if you have any suggestion how to make my code cleaner, cause I am pretty sure I am doing some extra stuff

0

There are 0 answers