0%

前言

這裡記錄一些 Heroku Postgres 常用的指令

由於我不算主攻資料庫,這些指令頂多在建立API時才會用到
真的很容易忘記
為自己做點紀錄,不用每次都去翻 doc
這篇文章會持續更新


SQL 語法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
-- 新建資料庫
CREATE DATABASE name;

-- 更改資料庫名稱
ALTER DATABASE <name> RENAME TO <newname>


-- 刪除整個資料表
DROP TABLE table_name;

-- 刪除資料表中的內容,但保留資料表
TRUNCATE TABLE table_name;

-- 刪除整個資料庫
DROP DATABASE database_name;

--顯示某 table 的所有欄位
SELECT column_name
FROM information_schema.columns
WHERE table_name = 'table_issues'
AND table_schema = 'public';

遠端 heroku postgres 操作

  • 查看現有備份檔
    heroku pg:backups

  • 立刻建立備份
    (指定app) heroku pg:backups:capture --app taiwan-astronomy-network-api
    (指定database) heroku pg:backups:capture table_issues

  • 排程備份
    heroku pg:backups:schedule --at "06:00 Asia/Taipei"
    flag –at 是必需參數,格式為: “hour:00 full TZ format
    Windows 必須使用雙引號
    Full TZ format 查詢: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones

  • 查看排程
    heroku pg:backups:schedules

  • 取消排程
    heroku pg:backups:unschedule DATABASE_URL
    DATABASE_URL: 如果一個 APP 有多個 DATABASE,則需指定 DATABASE 的 URL

  • 下載備份
    heroku pg:backups:download BACKUP_ID -o OUTPUT_NAME
    BACKUP_ID: 要下載的備份檔id,可先用 heroku pg:backups 查詢
    OUTPUT_NAME: 輸出的路徑與檔名,預設為 latest.dump,但如果沒有設定的話不會覆寫同名檔案,而是變成latest.demp.1

本地 postgres 操作

  • 用 latest.dump 復原本地資料庫
    pg_restore --verbose --clean --no-acl --no-owner -h localhost -U postgres -d tan_data latest.dump

前言

繼前兩篇我們成功在本地端為我們的 flask api 串接資料庫
現在我們要在 Heroku 上做一樣的事情
恩… 應該說目標一樣
但要做的設定還蠻不一樣的
繼續往下看吧!

在 Heroku 串接 API 和 Postgres

首先我們需要在 Heroku 上啟用一個外掛
叫 “Heroku Postgres”
你可以開瀏覽器到 Dashboard
Resources > Add-ons > Heruku Postgres

接下來會詢問你要用什麼方案
稍微看了一下發現居然有每個月 16,000 美元的方案OAO
好扯喔
記得在查資料的過程中看到有人說
「也許 Heroku 算不上便宜 (或許可以說它是最貴的)」
不過幸好我們的用量不高
TAN 也根本沒人要看吧! (誤
我們就選免費的ㄅ

以上這些步驟可以用一行命令完成:

heroku addons:create heroku-postgresql:hobby-dev --app <heroku_app_name>

用 –app 這個 flag 可以指定 app 名稱
如果你在 heroku 上有多個 app,指定一下比較不會出錯

再來你需要一組 uri 作為 SQLALCHEMY_DATABASE_URI 的設定值,執行
heroku config --app <heroku_app_name>
他就會給你一長串postgres://.........的 uri,但直接使用這組 uri 會出錯
我們稍微把它改一下,變成postgresql://........,這樣就可以了

打開app.py,把之前設定 SQLALCHEMY_DATABASE_URI 的部分改成

1
2
3
4
5
6
7
8
9
ENV = 'prod'
if ENV == "dev":
app.debug = True
app.config["SQLALCHEMY_DATABASE_URI"] = 'postgresql://postgres:et0997@localhost/TAN_test_data'
else:
app.debug = False
app.config["SQLALCHEMY_DATABASE_URI"] = 'postgresql://.........'

app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False

這邊我令了一個 ENV 變數判斷現在是開發階段還是成品階段
如要回到本地測試,只要把 ENV 設為 dev 即可

然後我也把 debug 的設定放到這段的 if statement 中
所以程式中原本的app.run(debug=True)也可以改回app.run()

在 Heroku 建立 table

先確定你有依照上一篇的教學將專案 deploy 到 heroku 上
執行 heroku run python 後輸入指令

1
2
from app import db # 從 app.py 中引入 db 模組
db.create_all() # 在 app.config 中所指定的 database 中建立 table

如果要刪除 table 就用db.drop_all()

完成,之後就能夠用 ORM 指令操作 database 了!

在 heroku 上用 psql 檢視資料

如果想看 heroku 上的資料,執行
heroku pg:psql
就會進到 psql 的 shell 中

\list
這個指令能印出 post gres 中的所有資料庫
不過如果在 heroku postgres 上執行的話,他只會跳出一堆以亂數取名的資料庫,對我們來說其實沒什麼意義
但如果在本地端開 psql 的話,你看到的就會是你之前創立過的資料庫了
要切換所在資料庫,執行 \c <資料庫名稱>

\dt
這個指令會印出目前所在的資料庫中有哪些 table

接下來你就能用 SQL 來獲取資料
假設資料表名稱是 table_issues
SELECT * FROM table_issues

結語

這是我第一次架設 api
回頭一看發現學了好多東西
Flask, Flask-SQLAlchemy, Heroku, PostgreSQL
完全沒料到,原本以為只要學 Flask 就好 XD

不過也好啦,直接學了整個體系,包含api功能,架設到雲端,資料庫的存取
要不是我已經有了想達成的目標(優化TAN網站)
不然如果我只是單純想學做 API 的話可能只會學到 Flask 而已
之後的某月某日還是會需要惡補其他環節的

前言

寫到這才發現我之前漏了 heroku 的介紹…
趕快補一下

Heroku 設定

heroku 是一個雲端平台,意思是他提供我們一個在網路上的空間,可以存放資料
更重要的是,你可以利用它部屬網站、API,這樣你就能用網址連線到你的網站了

有一個在 heroku 不斷出現的詞彙叫做 Dyno
Dyno 是運行和響應請求的應用程序的實例,欲執行網站就至少要一個 Dyno
以我目前的理解,可以把它當作 heroku 版的 repo

在免費方案下,

  1. Dyno 有 550 小時/月的免費時數,若通過信用卡驗證,額外贈送 450 小時/月,總共免費時數為 1,000 小時/月,若多個 Dyno 執行則可分攤掉時數
  2. Dyno 在 30 分鐘內沒有任何流量,系統自動進入睡眠狀態,睡眠狀態下則不消耗時數
  3. 睡眠狀態下 Dyno 收到請求,等喚醒約20秒啟動系統
  4. 儲存空間為 512MB

我已經在 Heroku 上建立帳號,建立新 app 叫做 taiwan-astronomy-network-api
然後便可繼續以下的步驟

一些設定檔

三份檔案要建立
runtime.txt 放的是這份專案所使用的 python 版本

1
python-3.9.6

requirements.txt 放的是這份專案所需要的模組
執行 pip freeze > requirements.txt 即可

Procfile 是heroku運行所需的檔案,注意沒有副檔名,P要大寫

1
web gunicorn app:app

第一個 app 對應的是 app.py 檔名的 app
第二個 app 對應的是 app.py 中 app = Flask(__name__) 的這個 app

這三個檔案稍有不對就會出錯
所以在繼續往下走前一定要再三確認

部屬專案

先到這裡安裝 heroku-cli

接著部屬專案的步驟如下:

heroku login

heroku git:remote -a <app名稱>

1
2
3
$ git add .
$ git commit -am "make it better"
$ git push heroku master

這邊不一定要用 master 要看你本地 repo 是在什麼 branch 上

到這邊應該沒問題了,趕緊下一篇就來串接資料庫!