首页 > 解决方案 > 如何在我的 flask-sqlalchemy 应用程序中使用 Heroku Postgres?

问题描述

现在我有一个应用程序将用户数据写入一个名为 users.sql 的数据库文件。但是,我通过 github 将其推送到 heroku 并且数据没有保留。如果某个时间过去了,heroku 将休眠,并且在检测到另一个登录时必须重新部署所有文件。我听说我可以将 heroku postgres 添加为 heroku 的插件,但我不确定如何将它与我当前的代码集成。我该怎么做才能设置它?

标签: pythonflaskherokuflask-sqlalchemy

解决方案


我在尝试将我的应用程序连接到 Postgres 时偶然发现了您的问题,并且对缺乏明确的说明感到非常沮丧。所以这是我努力克服的所有错误的分步过程(因为这就是教程让你喘不过气来的地方,而他们却不知不觉地雷声大作......)

TL;博士

  • 安装 Postgres
  • 安装 Heroku CLI
  • 安装 psycopg2 或 psycopg2-binary 和 gunicorn
  • 在 Heroku 中使用 Postgres 数据库创建一个应用程序,并将数据库 url 保存为SQLALCHEMY_DATABASE_URI
  • 创建 Procfile、requirements.txt 和 runtime.txt
  • 推送到 Github 并将 repo 连接到 Heroku
  • 部署分支
  • from app import db db.create_all()

我使用 WSL,所以我的答案中的所有命令行语法都是 Bash,我正在使用 Windows 10。

我的部分工作来自Traversy Media的 youtube教程。这是他使用的Github 存储库(我绝对建议最初使用基本应用程序,而不是为带有额外包的复杂应用程序中出现的错误而苦苦挣扎)。

在你开始之前

预赛

  • 创建一个虚拟环境并安装所有包。确保您拥有psycopg2并且gunicorn
 ERROR: Failed building wheel for psycopg2-binary

无论出于何种原因,psycopg 拒绝在我的系统上安装。您可以通过使用pip3 install psycopg2-binary来解决这个问题 - 就我们的要求而言,没有区别。

连接到 Postgres

从开始菜单打开 pgAdmin 4。如果您是第一次登录或已注销,这可能会提示您输入密码。

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?

用于sudo service postgresql status检查 PostgreSQL 服务器是否正在运行。如果是,请尝试停止并启动它。如果不是,请启动它。

sudo service postgresql start

sudo service postgresql stop

在左侧面板中,右键单击Databases并单击 Create > Database...。输入您的数据库名称(本教程使用“lexus”)并保存。

app.py(或您进行数据库配置的任何地方)找到该行

if ENV == 'dev':
    ...
    app.config['SQLALCHEMY_DATABASE_URI'] = ''

并将数据库连接字符串放在引号内。语法是

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.

就我而言,连接字符串是:

app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:123456@localhost/lexus'

进入python控制台,创建数据库:

>>> from app import db
>>> db.create_all()

如果你没有得到任何错误,认为自己是自切片面包以来最幸运的事情。在 pgAdmin 中,转到 Databases > [your db name] > Schemas > Tables 以检查它们是否已创建。

ImportError: cannot import name 'db' from 'app' (unknown location)

db不在app您的应用程序中。找到它的定义位置并从那里导入。

(psycopg2.OperationalError) FATAL:  password authentication failed for user "postgres"

您使用了错误的密码。我发现这很混乱,因为不清楚您是否需要使用主密码(您第一次登录 pgAdmin 时设置的密码)或您要连接的数据库的密码。这是这里需要的主密码。在命令行中输入psql -h 127.0.0.1 postgres( psql -h [ip address] [username]) - 验证密码是连接字符串所需的密码。

(psycopg2.OperationalError) FATAL:  database "lexus" does not exist

您可能使用错误的用户名连接到错误的数据库,或者您的数据库尚未创建。检查您的连接字符串和 pgAdmin 以确认详细信息是否正确。

db.create_all() seemed to work, but I have no tables in pgAdmin!

如果您的数据库模型存储在单独的文件中,请在初始化app.py后将它们导入。db它应该如下所示:

app = Flask(__name__)
...
db = SQLAlchemy(app)
...
from app.models import *

将数据发送到 Postgres

运行应用程序并通过表单提交一些数据(或在表中创建一些数据)。在 pgAdmin 中,右键单击刚刚创建的表并刷新,然后右键单击并查看/编辑数据。

Could not send data to server: Socket is not connected (0x00002749/10057) could not send SSL negotiation packet: Socket is not connected (0x00002749/10057)
  1. 断开并重新连接服务器(右键单击服务器并单击断开服务器,然后单击连接服务器)并再次刷新表。
  2. 如果这不起作用,请右键单击服务器并单击属性,转到连接选项卡并将主机名/地址从 更改 localhost127.0.0.1. 然后重复步骤 1。

创建 Heroku 应用

由于我更喜欢​​直接在 Github 而不是 CLI 中使用 Heroku,所以我没有git init在这里使用,但请注意,如果您的代码还不是 Github 存储库,则需要使用它。

在命令行中:

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. 

返回到您之前设置的代码,然后在块中app.config['SQLALCHEMY_DATABASE_URI']插入新的 url 。else它应该或多或少像这样:

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'

如果您正在使用本教程的 github 存储库,请设置ENV = 'prod',否则将配置设置为根据需要使用 heroku url。

如果您的项目文件中尚未包含以下文件,请将它们添加到您的根目录:

# 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.

将所有内容推送到 Github(同样,如果你已经在一个 repo 中,否则你将使用我没有关注的 Heroku CLI 进程)。

在 Heroku 上部署

单击您之前在Heroku 仪表板中创建的应用程序,然后转到 Deploy 选项卡。在部署方法选项中,单击 Github。连接您的 Github 帐户和存储库。

向下滚动到手动部署部分并选择您要部署的分支(或者如果这是唯一的,则将其保留为主分支)。单击部署分支。

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

看起来python版本是错误的。检查runtime.txt是否显示正确的 python 版本。如果不是,请更新它,删除并重新创建requirements.txt,推送到 Github 并再次单击 Deploy Branch。

创建 Heroku 数据库

回到命令行:

heroku run python3
>>> from app import db
>>> db.create_all()

要检查您的数据库,请输入

heroku pg:psql --app unique-app-name

如果您运行select * from tablename;,则不会返回任何内容,因为还没有任何数据。

单击 Heroku 中的查看按钮以打开您的应用程序。提交表单(或输入数据,但您的应用程序可以运行),然后select * from tablename;再次运行,您将看到该行数据。


推荐阅读