How to use Flask / Peewee with Heroku?

I am trying to deploy a Flask Heroku application. I am using Peewee as an ORM for a Postgres database. When I follow Heroku’s standard Flask deployment steps , the web process crashes after entering heroku ps:scale web=1 . Here's what the magazines say:

 Starting process with command `python app.py` /app/.heroku/venv/lib/python2.7/site-packages/peewee.py:2434: UserWarning: Table for <class 'flask_peewee.auth.User'> ("user") is reserved, please override using Meta.db_table cls, _meta.db_table, Traceback (most recent call last): File "app.py", line 167, in <module> auth.User.create_table(fail_silently=True) File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 2518, in create_table if fail_silently and cls.table_exists(): File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 2514, in table_exists return cls._meta.db_table in cls._meta.database.get_tables() File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 507, in get_tables ORDER BY c.relname""") File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 313, in execute cursor = self.get_cursor() File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 310, in get_cursor return self.get_conn().cursor() File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 306, in get_conn self.connect() File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 296, in connect self.__local.conn = self.adapter.connect(self. database, **self.connect_kwargs) File "/app/.heroku/venv/lib/python2.7/site-packages/peewee.py", line 199, in connect return psycopg2.connect(database=database, **kwargs) File "/app/.heroku/venv/lib/python2.7/site-packages/psycopg2/__init__.py", line 179, in connect connection_factory=connection_factory, async=async) psycopg2.OperationalError: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"? Process exited with status 1 State changed from starting to crashed 

I tried a bunch of different things to get Heroku to allow my application to talk to db Postgres, but no luck. Is there an easy way to do this? What do I need to do to configure Flask / Peewee so that I can use db on Heroku?

+4
source share
4 answers

Are you parsing the DATABASE_URL environment variable? It will look something like this:

 postgres://username: password@host :port/database_name 

So you will want to pull this out and analyze it before opening a connection to your database. Depending on how you declared your database (in your config or next to your wsgi application), it may look like this:

 import os import urlparse urlparse.uses_netloc.append('postgres') url = urlparse.urlparse(os.environ['DATABASE_URL']) # for your config DATABASE = { 'engine': 'peewee.PostgresqlDatabase', 'name': url.path[1:], 'password': url.password, 'host': url.hostname, 'port': url.port, } 

See notes here: https://devcenter.heroku.com/articles/django

+3
source

heroku config: set HEROKU = 1

 import os import urlparse import psycopg2 from flask import Flask from flask_peewee.db import Database if 'HEROKU' in os.environ: DEBUG = False urlparse.uses_netloc.append('postgres') url = urlparse.urlparse(os.environ['DATABASE_URL']) DATABASE = { 'engine': 'peewee.PostgresqlDatabase', 'name': url.path[1:], 'user': url.username, 'password': url.password, 'host': url.hostname, 'port': url.port, } else: DEBUG = True DATABASE = { 'engine': 'peewee.PostgresqlDatabase', 'name': 'framingappdb', 'user': 'postgres', 'password': 'postgres', 'host': 'localhost', 'port': 5432 , 'threadlocals': True } app = Flask(__name__) app.config.from_object(__name__) db = Database(app) 

Modified coleifer response for hasenj comment response. Please mark one of them as the accepted answer.

+3
source

I managed to get my Flask application in which Peewee is working on Heroku using the code below:

 # persons.py import os from peewee import * db_proxy = Proxy() # Define your models here class Person(Model): name = CharField(max_length=20, unique=True) age = IntField() class Meta: database = db_proxy # Import modules based on the environment. # The HEROKU value first needs to be set on Heroku # either through the web front-end or through the command # line (if you have Heroku Toolbelt installed, type the following: # heroku config:set HEROKU=1). if 'HEROKU' in os.environ: import urlparse, psycopg2 urlparse.uses_netloc.append('postgres') url = urlparse.urlparse(os.environ["DATABASE_URL"]) db = PostgresqlDatabase(database=url.path[1:], user=url.username, password=url.password, host=url.hostname, port=url.port) db_proxy.initialize(db) else: db = SqliteDatabase('persons.db') db_proxy.initialize(db) if __name__ == '__main__': db_proxy.connect() db_proxy.create_tables([Person], safe=True) 

You should already have a Postgres database add-on attached to your application. You can do this through the command line or through the web interface. Assuming the database is already tied to your application, and you have already deployed it with the above changes, log in to Heroku and create the table (s):

 $ heroku login $ heroku run bash $ python persons.py 

Make sure the table is created:

 $ heroku pg:psql your_app_name::DATABASE=> \dt 

Then you import this file (person.py in this example) into another Python script, for example. request handler. You need to directly manage the database connection:

 # server.py from flask import g from persons import db_proxy @app.before_request def before_request(): g.db = db_proxy g.db.connect() @app.after_request def after_request(response): g.db.close() return response … 

Literature:

+1
source

According to Peewee docs, you do not want to use Proxy() if your local database driver is not different from your remote (that is, locally, you use SQLite and use Postgres remotely). If, however, you use Postgres both locally and remotely, this is much simpler. In this case, you want to change the connection values ​​(database name, username, password, host, port, etc.) at run time and you do not need to use Proxy() .

Peewee has a built-in URL parser for database connections . Here's how to use it:

 import os from peewee import * from playhouse.db_url import connect db = connect(os.environ.get('DATABASE_URL')) class BaseModel(Model): class Meta: database = db 

In this example, the peewee db_url module reads the DATABASE_URL environment variable and parses it to extract the corresponding connection variables. Then it creates a PostgresqlDatabase object with these values.

Locally, you want to set DATABASE_URL as an environment variable. You can do this according to the instructions of any shell that you use. Or, if you want to use the Heroku target chain (start your local server using heroku local ), you can add it to a file named .env at the top of your project level . For remote configuration, you will want to add your database URL as a remote Heroku environment variable . You can do this with the following command:

 heroku config:set DATABASE_URL=postgresql://myurl 

You can find this URL by going to Heroku, going to your database and clicking "database credentials". It is listed in the URI section.

0
source

Source: https://habr.com/ru/post/1414384/


All Articles