After establishing a database using heroku addons:create heroku-postgresql:hobby-dev, I tried to migrate my local database to heroku database. So I first ran
heroku python manage.py migrate. After that I created a dump file of my local database using pg_dump -Fc --no-acl --no-owner -h localhost -U myuser mydb > mydb.dump. I uploaded my mydb.dump file to dropbox and then used the following command to load the dump to my heroku database
heroku pg:backups restore'https://www.dropbox.com/s/xkc8jhav70hgqfd/mydb.dump?' HEROKU_POSTGRESQL_COLOR_URL
But, that throws the following error -
r004 ---restore---> HEROKU_POSTGRESQL_PURPLE
[0KRunning... 0.00B..
[0KAn error occurred and your backup did not finish.
Please run `heroku pg:backups info r004` for details.
And on running heroku pg:backups info r004 I get -
Database: BACKUP
Started: 2015-06-25 18:19:37 +0000
Finished: 2015-06-25 18:19:38 +0000
Status: Failed
Type: Manual
Backup Size: 0.00B
=== Backup Logs
2015-06-25 18:19:38 +0000: waiting for restore to complete
2015-06-25 18:19:38 +0000: pg_restore: [archiver] did not find magic string in file header
2015-06-25 18:19:38 +0000: restore done
2015-06-25 18:19:38 +0000: waiting for download to complete
2015-06-25 18:19:38 +0000: download done
There is not much information on this error online and I can't figure out what the problem is.
If the database is small and you feel lucky this might do it
pg_dump --no-acl --no-owner -h localhost -U myuser myd | heroku pg:psql
I've had this error too and my solution was a little different. The problem was related to the format used. I needed to use --format=c when dumping the db.
To solve it I dumped the db again using --format=c
pg_dump --no-acl --no-owner --format=c database_name > db.dump
Then importing it to my heroku app
heroku pg:backups restore 'url_for_db.dump' DATABASE_URL
Hope this helps someone in the future!
You can use :
heroku pg:push mylocaldb HEROKU_POSTGRESQL_MAGENTA --app sushi
source: https://devcenter.heroku.com/articles/heroku-postgresql#pg-push
For windows users;
heroku pg:backups:restore "https://s3.amazonaws.com/me/items/3H0q/mydb.dump" DATABASE_URL
According to the official docs, be sure to use double-quotes around the remote url if you're using windows. see official docs
Related
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...)
TL;DR
Install Postgres
Install the Heroku CLI
Install psycopg2 or psycopg2-binary and gunicorn
Create an app in Heroku with a Postgres database and save the database url as the SQLALCHEMY_DATABASE_URI
Create Procfile, requirements.txt and runtime.txt
Push to Github and connect repo to Heroku
Deploy branch
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).
Before you start
Create an account in Heroku and install the Heroku CLI
Download and install PostgreSQL (this will also give you pgAdmin 4)
Fork and clone the Github repo, and check it runs ok (if you're not working with your own app)
Preliminaries
Create a virtual env and install all packages. Ensure you have psycopg2and 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.
Connect to Postgres
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 in app 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 after db is initialised. It should look like this:
app = Flask(__name__)
...
db = SQLAlchemy(app)
...
from app.models import *
Send data to Postgres
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 to 127.0.0.1. Then repeat step 1.
Create Heroku app
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).
Deploy on Heroku
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 recreate requirements.txt, push to
Github and click Deploy Branch again.
Create Heroku database
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.
In your init.py file you can set up your app.config['SQLALCHEMY_DATABASE_URI'] variable such that it will look for the one Heroku will give your application if it's running on heroku, OR use the configuration for your local database if it's running locally. You can achieve this as such:
app.config['SQLALCHEMY_DATABASE_URI'] = environ.get('DATABASE_URL') or "postgresql://postgres:password#localhost:5432/postgres"
replace what is after the OR w/ the connection details for your local connection
I would suggest considering setting up a local postgres database instead of sql if you're going to use heroku but you can technically use both. You just may run into minor issues, I have ran into issues w/ dates being handled slightly different, for example.
Firstly make heroku login from terminal:
$ heroku login
Now create the database for your app using following command:
$ heroku addons:create heroku-postgresql:hobby-dev --app app_name
Now after your Database has been created, get the URL of your Database using the following command:
$ heroku config --app app_name
Now that you have got your Database URL, replace the value of app.config[‘SQLALCHEMY_DATABASE_URI’] line in the “app.py” file with this Database URL:
app.config['SQLALCHEMY_DATABASE_URI'] = 'heroku_database_url'
And finally push code to heroku.
I've been having a hard time trying to get a successful deployment of my Django Web App to AWS' Elastic Beanstalk. I am able to deploy my app from the EB CLI on my local machine with no problem at all until I add a list of container_commands config file inside a .ebextensions folder.
Here are the contents of my config file:
container_commands:
01_makeAppMigrations:
command: "django-admin.py makemigrations"
leader_only: true
02_migrateApps:
command: "django-admin.py migrate"
leader_only: true
03_create_superuser_for_django_admin:
command: "django-admin.py createfirstsuperuser"
leader_only: true
04_collectstatic:
command: "django-admin.py collectstatic --noinput"
I've dug deep into the logs and found these messages in the cfn-init-cmd.log to be the most helpful:
2020-06-18 04:01:49,965 P18083 [INFO] Config postbuild_0_DjangoApp_smt_prod
2020-06-18 04:01:49,991 P18083 [INFO] ============================================================
2020-06-18 04:01:49,991 P18083 [INFO] Test for Command 01_makeAppMigrations
2020-06-18 04:01:49,995 P18083 [INFO] Completed successfully.
2020-06-18 04:01:49,995 P18083 [INFO] ============================================================
2020-06-18 04:01:49,995 P18083 [INFO] Command 01_makeAppMigrations
2020-06-18 04:01:49,998 P18083 [INFO] -----------------------Command Output-----------------------
2020-06-18 04:01:49,998 P18083 [INFO] /bin/sh: django-admin.py: command not found
2020-06-18 04:01:49,998 P18083 [INFO] ------------------------------------------------------------
2020-06-18 04:01:49,998 P18083 [ERROR] Exited with error code 127
I'm not sure why it can't find that command in this latest environment.
I've deployed this same app with this same config file to a prior beanstalk environment with no issues at all. The only difference now is that this new environment was launched within a VPC and is using the latest recommended platform.
Old Beanstalk environment platform: Python 3.6 running on 64bit Amazon Linux/2.9.3
New Beanstalk environment platform: Python 3.7 running on 64bit Amazon Linux 2/3.0.2
I've ran into other issues during this migration related to syntax updates with this latest platform. I'm hoping this issue is also just a simple syntax issue, but I've dug far and wide with no luck...
If someone could point out something obvious that I'm missing here, I would greatly appreciate it!
Please let me know if I can provide some additional info!
Finally got to the bottom of it all, after deep-diving through the AWS docs and forums...
Essentially, there were a lot of changes that came along with Beanstalk moving from Amazon Linux to Amazon Linux 2. A lot of these changes are vaguely mentioned here.
One major difference for the Python platform as mentioned in the link above is that "the path to the application's directory on Amazon EC2 instances of your environment is /var/app/current. It was /opt/python/current/app on Amazon Linux AMI platforms." This is crucial for when you're trying to create the Django migrate scripts as I'll explain further in detail below, or when you eb ssh into the Beanstalk instance and navigate it yourself.
Another major difference is the introduction of Platform hooks, which is mentioned in this wonderful article here. According to this article, "Platform hooks are a set of directories inside the application bundle that you can populate with scripts." Essentially these scripts will now handle what the previous container_commands handled in the .ebextensions config files. Here is the directory structure of these Platform hooks:
Knowing this, and walking through this forum here, where wonderful community members went through the trouble of filling in the gaps in Amazon's docs, I was able to successfully deploy with the following file set up:
(Please note that "MDGOnline" is the name of my Django app)
.ebextensions\01_packages.config:
packages:
yum:
git: []
postgresql-devel: []
libjpeg-turbo-devel: []
.ebextensions\django.config:
container_commands:
01_sh_executable:
command: find .platform/hooks/ -type f -iname "*.sh" -exec chmod +x {} \;
option_settings:
aws:elasticbeanstalk:application:environment:
DJANGO_SETTINGS_MODULE: MDGOnline.settings
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: static
/static_files: static_files
aws:elasticbeanstalk:container:python:
WSGIPath: MDGOnline.wsgi:application
.platform\hooks\predeploy\01_migrations.sh:
#!/bin/bash
source /var/app/venv/*/bin/activate
cd /var/app/staging
python manage.py makemigrations
python manage.py migrate
python manage.py createfirstsuperuser
python manage.py collectstatic --noinput
Please note that the '.sh' scripts need to be linux-based. I ran into an error for a while where the deployment would fail and provide this message in the logs: .platform\hooks\predeploy\01_migrations.sh failed with error fork/exec .platform\hooks\predeploy\01_migrations.sh: no such file or directory .
Turns out this was due to the fact that I created this script on my windows dev environment. My solution was to create it on the linux environment, and copy it over to my dev environment directory within Windows. There are methods to convert DOS to Unix out there I'm sure. This one looks promising dos2unix!
I really wish AWS could document this migration better, but I hope this answer can save someone the countless hours I spent getting this deployment to succeed.
Please feel free to ask me for clarification on any of the above!
EDIT: I've added a "container_command" to my config file above as it was brought to my attention that another user also encountered the "permission denied" error for the platform hook when deploying. This "01_sh_executable" command is to chmod all of the .sh scripts within the hooks directory of the app, so that Elastic Beanstalk can have the proper permission to execute them during the deployment process. I found this container command solution in this forum here:
This might work
.ebextensions/django.config
option_settings:
aws:elasticbeanstalk:container:python:
WSGIPath: mysite.wsgi:application
aws:elasticbeanstalk:environment:proxy:staticfiles:
/static: static
packages:
yum:
python3-devel: []
mariadb-devel: []
container_commands:
01_collectstatic:
command: "source /var/app/venv/staging-LQM1lest/bin/activate && python manage.py collectstatic --noinput"
02_migrate:
command: "source /var/app/venv/staging-LQM1lest/bin/activate && python manage.py migrate --noinput"
leader_only: true
This works for me.
container_commands:
01_migrate:
command: "source /var/app/venv/*/bin/activate && python /var/app/staging/manage.py migrate --noinput"
leader_only: true
So i used postgres in development for my django project and have important entries in there and i want to deploy to my app in heroku
is there a simple way to do this?
Sure. You just need to export your local database and import it on the Heroku Postgres database. Heroku has a guide to do just that.
Create a dump from your local database. PGPASSWORD=mypassword pg_dump -Fc --no-acl --no-owner -h localhost -U myuser mydb > mydb.dump
Upload mydb.dump somewhere Heroku can access it.
Import to heroku. heroku pg:backups restore 'https://s3.amazonaws.com/me/items/3H0q/mydb.dump' DATABASE_URL
Source
I first tried using heroku addons:add pgbackups but heroku docs say that it has been deprecated. The instead recommended using this command as specified here
PGPASSWORD=mypassword pg_dump -Fc --no-acl --no-owner -h localhost -U myuser mydb > mydb.dump
But this throws the following error-
'PGPASSWORD' is not recognized as an internal or external command,
operable program or batch file.
I have already existing data on my local database and want to transfer those data into the heroku database. Any way to make this work or is there some other way?
You could try fixtures
To create the JSON file from your local database:
python manage.py dumpdata > a_fixture_file.json
Take that file to the server. Be sure your server database has the same migrations. Then
python manage.py loaddata a_fixture_file.json
I'm trying to deploy my first app using Python/Flask on Heroku. I don't really know what I'm doing and am just following the tutorial at https://devcenter.heroku.com/articles/python#prerequisites. When I type the command heroku ps:scale web=1 I'm getting the error message "No such type as web". My Procfile says web: python scrabble_cheater.py, which I believe is correct. Here's the log of my terminal:
(venv)jason-olsens-macbook-pro:scrabble paulnichols$ heroku status
=== Heroku Status
Development: No known issues at this time.
Production: No known issues at this time.
(venv)jason-olsens-macbook-pro:scrabble paulnichols$ heroku config
=== enigmatic-mountain-1395 Config Vars
LANG: en_US.UTF-8
LD_LIBRARY_PATH: /app/.heroku/vendor/lib
LIBRARY_PATH: /app/.heroku/vendor/lib
PATH: /app/.heroku/venv/bin:/bin:/usr/local/bin:/usr/bin
PYTHONHASHSEED: random
PYTHONHOME: /app/.heroku/venv/
PYTHONPATH: /app/
PYTHONUNBUFFERED: true
(venv)jason-olsens-macbook-pro:scrabble paulnichols$ heroku ps
(venv)jason-olsens-macbook-pro:scrabble paulnichols$ git push heroku master
Warning: Permanently added the RSA host key for IP address '50.19.85.154' to the list of known hosts.
Everything up-to-date
(venv)jason-olsens-macbook-pro:scrabble paulnichols$ heroku ps:scale web=1
Scaling web processes... failed
! No such type as web
(venv)jason-olsens-macbook-pro:scrabble paulnichols$
Any help is greatly appreciated!
Procfile was saved with a .txt extension by mistake--once I removed the extension it worked.