cs50x final project在我苦思將近一個月、到處亂撞技術的厚牆之後,決定從簡單開始,使用教授課內教的flask搭配postgresql做為資料庫做一個web-app並架在heroku上使用。


idea

在離開台北之前去做了最後一次光療,突然發現每次做完指甲,美甲師總是會問我「你生日幾月?」,問完幾月之後會問「你生日幾號?」,他需要在厚厚的數十本的顧客資料夾中翻找出我的資料,雖然用生日做排列查找已經是不錯的方法,但如果可以有前端互動跟後端資料庫應該更方便吧(我心想)所以牙一咬決定自己從頭開始刻,順便當作final project交出去一舉兩得xd


Flask + PostgreSQL

資料夾裡所有會用到的東西架構大概如下:

.
├── Procfile
├── app.py
├── models.py
├── manage.py
├── flask_session
├── migrations
├── manicure.db
├── requirements.txt
├── static
└── templates
    ├── index.html
    ├── layout.html
    ├── login.html
    ├── register.html
    ├── success.html
    ├── topup.html
    ├── transaction.html
    └── user.html

啟用database的時候記得跑完下面三條指令:

python3 manage.py db init
python3 manage.py db migrate
python3 manage.py db upgrade


errors

1. local

ModuleNotFoundError: No module named 'flask._compat'
ImportError: cannot import name 'MigrateCommand' from 'flask_migrate'

嘗試在local run python3 app.py的時候被一些module error阻擋(如上),查了一下發現是版本問題,我的case把flask降到1.1.4、把flask_migrate降到2.5.3就ok了。

2. heroku

  • 檔案打架

推到heroku之後造訪網頁,毫無意外地收到Application Error,於是乖乖的用heroku logs --tail開始慢慢除錯。我得到的全部都是H10 "App crashed"的錯誤,網路上大部分的資訊說這是因為Procfile裡面有bug,所以我跟著把Procfile改來改去但還是一樣錯誤。直到最後我細細地想過一遍我資料夾裡面每個檔案的用途,發現我有Pipfile也有requirements.txt但基本上這兩個檔案的作用是一樣的,都是declare目前使用的各個套件的版本。所以最後我把Pipfile刪掉只留requirements.txt就deploy成功了。

  • 連接不到Heroku Postgres
sqlalchemy.exc.NoSuchModuleError: Can't load plugin: sqlalchemy.dialects:postgres

查了一下原因,原來這是database URI錯誤的問題。Heroku Postgres直接給的環境變數DATABASE_URI開頭是postgres://但是開頭是postgresql://的URI才能成功連接。於是這邊的做法會是寫一個if statement把URI的開頭換掉。

basedir = os.path.abspath(os.path.dirname(__file__))
# either run on heroku env or local
DATABASE_URI = os.environ.get('DATABASE_URL') or 'sqlite:///'+ os.path.join(basedir, 'myDB.db')
if DATABASE_URI.startswith("postgres://"):
    DATABASE_URI = DATABASE_URI.replace("postgres://", "postgresql://")
app.config['SQLALCHEMY_DATABASE_URI'] = DATABASE_URI


📚心得:

算是在14天隔離生活中努力生出來的小專案,也因此可以把奮鬥了大半年的cs50結束了。遇到解不開的error還是會很挫折,但是慢慢可以告訴自己後退一點、休息一下,腦子清楚的時候再去好好地問google,有方法的:)


參考資源: