How to use Flask-Migrate with Google App Engine? - python

Since I moved to Google App Engine I cannot run the Flask-Migrate command python manage.py db migrate because I have exceptions regarding some GAE related imports (No module named google.appengine.ext for example).
Is there a way to run this, or an alternative, to upgrade my database on GAE?

Yes, there is a way to run it, though it's not as straightforward as you'd might like.
You need to configure your Google Cloud SQL, add yourself as an authorized user (by entering your ip address) and request to have an IPv4 address. Deal with SSL as appropriate.
Using a script:
Replacing user, password, instance_id, db_name, and path below
# migrate_prod.py
DB_MIGRATION_URI = "mysql+mysqldb://user:password#instance_id/db_name?ssl_key=path/client-key.pem&ssl_cert=path/client-cert.pem&&ssl_ca=path/server-ca.pem"
from flask import Flask
from flask.ext.sqlalchemy import SQLAlchemy
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from models import * # not needed if migration file is already generated
app = Flask(__name__)
app.config["SQLALCHEMY_DATABASE_URI"] = DB_MIGRATION_URI
app.config["SQLALCHEMY_TRACK_MODIFICATIONS"] = False
db = SQLAlchemy(app)
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
Run the script as you would to migrate locally: python migrate_prod.py db upgrade, assuming your migration file is already there.
Release the IPv4, so that you're not charged for it.
I give much credit to other answers: how to connect via SSL and run alembic migrations on GAE (of which this is probably a duplicate).

Related

Having trouble getting Flask app running on cPanel using passenger_wsgi.py

I'm trying to get a Flask "point of sale" application working on cPanel with no success.
Here is the directory structure on cPanel File Manager
I have my app = Flask(name) in init.py
from flask import Flask
from config import Config
from flask_sqlalchemy import SQLAlchemy
from flask_migrate import Migrate
from flask_login import LoginManager
from flask_security import Security,SQLAlchemyUserDatastore
# from app.models import Role,User
app = Flask(__name__)
app.config.from_object(Config)
db = SQLAlchemy(app)
migrate = Migrate(app, db, render_as_batch=True)
login = LoginManager(app)
from app import routes,models
I have tried using the line this line of code in my passenger_wsgi.py
from app import app as application
and in my pointofsale.py i used:
application = app
I have successfully created the python app and installed requirements.txt, when I try to load the link to the website but I cant reach the site.
Managed to figure out the issue, I had two files importing the application instance -: pointofsale.py and passenger_wsgi.py.
I deleted pointofsale.py, and added the following code to passenger_wsgi.py file
from app import app
application = app

Flask start-up command on azure for 'manage.py runserver'

I am unable to run the python manage.py runserver command from Azure. My manage.py code is
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from flask_migrate import upgrade as upgrade_database
from glogic import app, db, prepare_app
prepare_app(environment='ms')
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == "__main__":
manager.run()
Where glogic is the package for the bulk of my python files. The prepare app method is called from the __init__.py file which is as follows:
from glogic.config import config_env_files
from flask import Flask
from flask_sqlalchemy import SQLAlchemy
# initialises app and db
db = SQLAlchemy()
app = Flask(__name__)
# prepares the app and db environment based on config files
def prepare_app(environment='ms', p_db=db):
app.config.from_object(config_env_files[environment])
p_db.init_app(app)
# load views by importing them
from . import views
return app
Running and hosting locally it all works but I have been unable to find the correct startup command or what to put in a startup.sh file in order to run the server on Azure.
When running locally, I can start it using the command gunicorn --bind=0.0.0.0 --timeout 600 manage:app but this isn't working on Azure

Running manage.py on Heroku for Flask app gives "could not connect"

I am trying to migrate my database on Heroku using heroku run python manage.py db migrate on my Flask app. But I am getting this error:
sqlalchemy.exc.OperationalError: (psycopg2.OperationalError) could not connect to server: Connection
refused
Is the server running on host "localhost" (127.0.0.1) and accepting
TCP/IP connections on port 5432?
Here is the code to my manage.py file:
import os
from flask_script import Manager
from flask_migrate import Migrate, MigrateCommand
from app import create_app, db
app=create_app()
with app.app_context():
migrate = Migrate(app, db)
manager = Manager(app)
manager.add_command('db', MigrateCommand)
if __name__ == '__main__':
manager.run()
Here is the configuration file to the database:
import os
class Config:
SECRET_KEY= os.environ.get('SECRET_KEY')
SQLALCHEMY_DATABASE_URI= os.environ.get('SQLALCHEMY_DATABASE_URI')
MAIL_SERVER='smtp.googlemail.com'
MAIL_PORT=587
MAIL_USE_TLS = True
MAIL_USERNAME= os.environ.get('EMAIL_USER')
MAIL_PASSWORD= os.environ.get('EMAIL_PASS')
I have set up the sqlalchemy_database_uri to a database in PostgreSQL in this format postgres://YourUserName:YourPassword#YourHost:5432/YourDatabase.
This error has been bugging me and I cannot find a solution anywhere.
Why isn't this working?
You can't connect your Heroku application to your local database without some major drawbacks. It's a huge pain to set up (you'll need to deal with port forwarding and likely at least one firewall, probably dynamic IP addresses, ...) and your application won't run if your laptop is off.
A better solution would be to have a database in the cloud, and given that you are already using Heroku and PostgreSQL the most natural choice is Heroku's own Postgres service. If you're depending on psycopg2, there's a good chance that one has already been provisioned for you.
If it has, you'll see a DATABASE_URL environment variable containing your connection string. Simply set your SQLAlchemy database URI from that:
SQLALCHEMY_DATABASE_URI= os.environ.get('DATABASE_URL')
If a database hasn't been provisioned for you (check by running heroku addons) you can provision one using the free tier easily:
heroku addons:create heroku-postgresql:hobby-dev
Note that you shouldn't be running manage.py db migrate on Heroku at all. This generates migration files, which will be lost on Heroku's ephemeral filesystem. Generate migrations locally, and commit the migration files. You'll want to run manage.py db upgrade in both places, though.

How to add custom build/deploy commands on OpenShift

I'm trying to properly build and deploy a Flask application to OpenShift.
The application uses SQLAlchemy as an ORM, and Flask-Migrate to do the database migrations.
My app resides in autoapp.py with the following content:
# -*- coding: utf-8 -*-
"""Create an application instance."""
from tcst_api.app import create_app
from tcst_api.utils import get_config_object
CONFIG = get_config_object()
application = create_app(CONFIG)
if __name__ == '__main__':
application.run()
To initialize the app and start it, I do the following locally:
export FLASK_APP=autoapp.py
flask db init
flask db migrate
flask db upgrade
flask run
On the OpenShift side, I managed to set up the FLASK_APP environment variable, and the platform also can hook the source and is able to build it.
However I don't know where can I inject the flask db ... commands into the process.
I use gunicorn to serve the app, and OpenShift manages to find.

Run Alembic migrations on Google App Engine

I have a Flask app that uses SQLAlchemy (Flask-SQLAlchemy) and Alembic (Flask-Migrate). The app runs on Google App Engine. I want to use Google Cloud SQL.
On my machine, I run python manage.py db upgrade to run my migrations against my local database. Since GAE does not allow arbitrary shell commands to be run, how do I run the migrations on it?
Whitelist your local machine's IP: https://console.cloud.google.com/sql/instances/INSTANCENAME/access-control/authorization?project=PROJECTNAME
Create an user: https://console.cloud.google.com/sql/instances/INSTANCENAME/access-control/users?project=PROJECTNAME
Assign an external IP address to the instance: https://console.cloud.google.com/sql/instances/INSTANCENAME/access-control/ip?project=PROJECTNAME
Use the following SQLAlchemy connection URI: SQLALCHEMY_DATABASE_URI = 'mysql://user:pw#ip:3306/DBNAME'
Remember to release the IP later as you are charged for every hour it's not used
It's all just code you can run, so you can create an admin endpoint with which to effect an upgrade:
#app.route('/admin/dbupgrade')
def dbupgrade():
from flask_migrate import upgrade, Migrate
migrate = Migrate(app, db)
upgrade(directory=migrate.directory)
return 'migrated'
(Dropwizard, for instance, caters nicely for such admin things via tasks)
You can whitelist the ip of your local machine for the Google Cloud SQL instance, then you run the script on your local machine.

Categories