Right now I have an app that write data for users to a database file called users.sql. However, I pushed this to heroku through github and the data doesn't stick. If a certain time has passed, heroku will sleep and all the files will have to be redeployed when another login is detected. I heard that I could add heroku postgres as an addon to heroku but I am not sure what to do to integrate this with my current code. What do I do to set it up?
I stumbled across your question while trying to connect my app to Postgres and getting very frustrated at the lack of clear instructions. So here's the step by step process with all the errors I struggled through (because that's where the tutorials leave you gasping for air while they thunder on obliviously...)
SQLALCHEMY_DATABASE_URI
from app import db
db.create_all()
I work with WSL so all command line syntax in my answer is Bash, and I'm working on Windows 10.
I'm working partly off a youtube tutorial by Traversy Media. Here's the Github repo he works with (I definitely recommend initially working with a basic app instead of struggling with the errors that crop up in a complex app with extra packages).
psycopg2
and gunicorn
ERROR: Failed building wheel for psycopg2-binary
For whatever reason, psycopg refuses to install on my system. You can get round this by using
pip3 install psycopg2-binary
instead - there's no difference as far as our requirements go.
Open pgAdmin 4 from the start menu. This may prompt you for a password if it's the first time you're logging in or if you were logged out.
could not connect to server: Connection refused (0x0000274D/10061) Is the server running on host "127.0.0.1" and accepting TCP/IP connections on port 5432?
Use
sudo service postgresql status
to check if the PostgreSQL server is running. If it is, try stopping and starting it. If it isn't, start it.
sudo service postgresql start
sudo service postgresql stop
In the left-hand panel, right-click on Databases
and click Create > Database.... Enter your database name (the tutorial uses "lexus") and save.
In app.py
(or wherever you do your database config) find the line
if ENV == 'dev':
...
app.config['SQLALCHEMY_DATABASE_URI'] = ''
and put the database connection string inside the quotes. The syntax is
postgresql://[username]:[password]@[host name]/[db name]
# [username] - Right-click on your server in pgAdmin (probably a variation of `PostgreSQL 13`). Go to the Connection tab and check the Username field.
# [password] - The root password you set the first time you logged in to pgAdmin.
# [host name] - In the same place as your username, in the Host name/address field.
# [db name] - The name you entered when creating your database.
In my case, the connection string is:
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:123456@localhost/lexus'
Important Disclaimer
This solution has you put the database password in code: app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:123456@localhost/lexus'
This saves the password in your version control history, where it can/will eventually allow anyone on the Internet to control your database. Yikes! Get DB user & password from env vars instead.
Thanks @Paul Cantrell!
Enter the python console and create the database:
>>> from app import db
>>> db.create_all()
If you didn't get an error on that, consider yourself the luckiest thing since sliced bread. In pgAdmin go to Databases > [your db name] > Schemas > Tables to check they've been created.
ImportError: cannot import name 'db' from 'app' (unknown location)
db
is not located inapp
in your application. Find where it's defined and import it from there.
(psycopg2.OperationalError) FATAL: password authentication failed for user "postgres"
You're using the wrong password. I found this confusing because it's unclear whether you need to use the master password (the one you set when logging in to pgAdmin for the first time) or the password for the database you're connecting to. It's the master password that's needed here. Enter
psql -h 127.0.0.1 postgres
(psql -h [ip address] [username]
) in the command line - the password that authenticates is the one you need for the connection string.
(psycopg2.OperationalError) FATAL: database "lexus" does not exist
You might be connecting to the wrong database, using the wrong username, or your database hasn't been created. Check your connection string and pgAdmin to confirm that details are correct.
db.create_all() seemed to work, but I have no tables in pgAdmin!
If your database models are stored in a separate file, import them into
app.py
afterdb
is initialised. It should look like this:app = Flask(__name__) ... db = SQLAlchemy(app) ... from app.models import *
Run the app and submit some data through the form (or create some data in your table). In pgAdmin, right-click the table you just created and refresh, then right-click and view/edit data.
Could not send data to server: Socket is not connected (0x00002749/10057) could not send SSL negotiation packet: Socket is not connected (0x00002749/10057)
- Disconnect and reconnect server (right-click on server and click Disconnect Server, then Connect Server) and refresh table again.
- If that didn't work, right-click on server and click Properties, go to the Connection tab and change the Host name/address from
localhost
to127.0.0.1
. Then repeat step 1.
Since I prefer using Heroku directly with Github instead of the CLI, I'm not using git init
here, but note that if your code is not already a Github repo you would need to use it.
In the command line:
heroku login # If you have the Heroku CLI installed correctly, this will open a tab in the browser and log you in to Heroku.
heroku create unique-app-name # (replace `unique-app-name` with your own name). This creates an app on the Heroku server, and it's the place your code is cloned to so that it can be run. Check that it has appeared in your [Heroku dashboard](https://dashboard.heroku.com/).
heroku addons:create heroku-postgresql:hobby-dev -a unique-app-name # This creates an empty postgres database for your app. Heroku uses its own database, not your pgAdmin database.
heroku config -a unique-app-name # The url you set earlier as the `SQLALCHEMY_DATABASE_URI` points to the database you created in pgAdmin, but since your app is now going to be using Heroku's database you need a new url. Copy the DATABASE_URL that is returned.
Go back to the code where you set app.config['SQLALCHEMY_DATABASE_URI']
earlier, and insert the new url inside the else
block. It should look more or less like this:
if ENV == 'dev':
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:123456@localhost/lexus'
else:
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgres://urlyoujustgotfromherokuozftkndvkayeyc:691196bfb1b1ca8318b733935b10c97a19fd41@ec2-52-71-161-140.compute-1.amazonaws.com:5432/d3pofh2b55a2ct'
If you're working with the tutorial's github repo, set ENV = 'prod'
, otherwise set the config to use the heroku url however you want.
Add the following files to your root directory if they're not yet included in your project files:
# Procfile
web: gunicorn app:app # The first `app` refers to the app.py and the second `app` refers to the app object, ie `app = Flask(__name__)`. Heroku needs this to know how to run your code.
# runtime.txt
python-3.8.5 # Find your python version by entering `python --version` or `python3 --version` in the command line.
# requirements.txt
# Create this by running `pip3 freeze > requirements.txt`. According to the [Heroku docs](https://devcenter.heroku.com/articles/python-runtimes)
# this must be done after changing runtime versions, so it's best to do it last.
Push everything to Github (again, this is if you're already in a repo otherwise you'd be using the Heroku CLI process which I'm not following).
Click on the app you created previously in the Heroku dashboard and go to the Deploy tab. In the Deployment method options, click Github. Connect your Github account and repository.
Scroll down to the Manual deploy section and select the branch you want to deploy (or just leave it as master if that's the only one). Click Deploy Branch.
Requested runtime (python-3.7.2) is not available for this stack (heroku-20). ! Aborting. More info: https://devcenter.heroku.com/articles/python-support ! Push rejected, failed to compile Python app. ! Push failed
It looks like the python version is wrong. Check that
runtime.txt
is showing the right python version. If it isn't, update it, delete and recreaterequirements.txt
, push to Github and click Deploy Branch again.
Back in the command line:
heroku run python3
>>> from app import db
>>> db.create_all()
To check out your database, enter
heroku pg:psql --app unique-app-name
If you run select * from tablename;
nothing will be returned because there isn't any data yet.
Click the View button in Heroku to open your app. Submit the form (or enter data however your app works), then run select * from tablename;
again and you'll see the row of data.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With