Reputation: 347
As my flask app should not write anything in my database, I set up Flask-SQLAlchemy to reflect my database. This way I do not have to change my models, when I change my schema:
# app/__init__.py
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
def create_app():
app = Flask(__name__)
db.init_app(app)
with app.app_context():
db.Model.metadata.reflect(db.engine)
# app/models.py
from app import db
class Data(db.Model):
__table__ = db.Model.metadata.tables['data']
This all works fine and dandy. But now, I wanted to implement tests using unittest. But I could not find anything how that is supposed to work? I am used to make a new sqlite database to test, but I don't have any Models to write there. What is the standard procedure here? Do you copy everything to sqlite? If so, how?
Upvotes: 0
Views: 2160
Reputation: 55600
There's no general rule for this situation: you database is decoupled from your application so you need to somehow get a copy of the database's schema to recreate locally.
Many database engines provide a way to dump a database schema to a file which in turn can be used to load a schema onto another server (or onto the same server with a different name).
If you want to stick to using Python and SQLAlchemy tools you could populate the database metadata via reflection on your production database, then use the metadata to create the tables on your local database.
Something like this: on the production server:
import pickle
import sqlalchemy as sa
engine = sa.create_engine(PRODUCTION_DATABASE_URI)
metadata = sa.MetaData()
metadata.reflect(engine)
# Save the metadata so that it can be transferred to another machine.
with open('metadata.pkl', 'wb') as f:
pickle.dump(metadata, f)
Then locally
# Restore the metadata object
with open('metadata.pkl', 'rb') as f:
metadata = pickle.load(f)
engine = sa.create_engine(TEST_DATABASE_URI)
# Create the tables
metadata.create_all(engine)
Upvotes: 3