介紹
在網絡應用程序中,通常需要使用數據庫,這是一個組織良好的數據集。您使用數據庫來存儲和維護可以有效檢索和操作的持久性數據。例如,在社交媒體應用程序中,您有一個數據庫,用於存儲用戶數據(個人信息、帖子、評論、關注者),以一種可以有效操作的方式存儲。您可以根據不同的要求和條件向數據庫中添加數據,檢索它,修改它或刪除它。在 Web 應用程序中,這些要求可能是用戶添加新帖子、刪除帖子或刪除他們的帳戶,這可能會刪除他們的帖子,也可能不會。您執行的操作來操作數據將取決於應用程序中的具體功能。例如,您可能不希望用戶添加沒有標題的帖子。
Flask 是一個輕量級的 Python 網頁框架,提供了在 Python 語言中創建 Web 應用程序所需的有用工具和功能。PostgreSQL,或稱 Postgres,是一個關聯式數據庫管理系統,提供了對 SQL 查詢語言的實現。它符合標準,具有許多高級功能,如可靠的事務和無需讀取鎖的並發。
在本教程中,您將構建一個小型的書評 Web 應用程序,演示如何使用 psycopg2
函式庫,這是一個 PostgreSQL 數據庫適配器,允許您在 Python 中與 PostgreSQL 數據庫進行交互。您將與 Flask 一起使用它來執行基本任務,如連接到數據庫服務器,創建表,將數據插入表中,以及從表中檢索數據。
先決條件
-
本地 Python 3 編程環境。請參照系列文章 如何安裝和設置本地 Python 3 編程環境 中的教程進行操作。在本教程中,專案目錄稱為
flask_app
。 -
對基本的 Flask 概念有一定的了解,比如路由、視圖函數和模板。如果你對 Flask 不太熟悉,可以查看《使用 Flask 和 Python 創建你的第一個 Web 應用》和《在 Flask 應用中使用模板》。
-
對基本的 HTML 概念有一定的了解。你可以閱讀我們的《如何使用 HTML 構建網站》教程系列來了解背景知識。
-
在您的本地机器上安装了PostgreSQL,并且可以访问PostgreSQL提示符。请按照在Ubuntu 20.04上安装和使用PostgreSQL设置您的PostgreSQL数据库。
步骤1 — 创建PostgreSQL数据库和用户
在此步骤中,您将创建一个名为flask_db
的数据库,并为您的Flask应用程序创建一个名为sammy
的数据库用户。
在Postgres安装过程中,创建了一个操作系统用户,名为postgres
,对应于postgres
PostgreSQL管理用户。您需要使用此用户执行管理任务。您可以使用sudo
并通过-iu
选项传递用户名。
使用以下命令登录到交互式Postgres会话:
您将获得一个PostgreSQL提示符,在那里您可以设置您的要求。
首先,为您的项目创建一个数据库:
注意:每个Postgres语句都必须以分号结束,所以如果您遇到问题,请确保您的命令以分号结尾。
接下来,为我们的项目创建一个数据库用户。确保选择一个安全的密码:
然后给这个新用户访问和管理你的新数据库的权限:
确认数据库已创建,通过输入以下命令来获取数据库列表:
您将在数据库列表中看到flask_db
。
当您完成后,退出PostgreSQL提示符,输入:
现在Postgres已设置好,您可以使用psycopg2
库通过Python连接和管理其数据库信息。接下来,您将安装此库以及Flask包。
第2步 — 安装Flask和psycopg2
在这一步中,您将安装Flask和psycopg2
库,以便您可以使用Python与数据库交互。
在您的虚拟环境激活的情况下,使用pip
安装Flask和psycopg2
库:
安装成功后,您将在输出的最后看到类似以下的一行:
Output
Successfully installed Flask-2.0.2 Jinja2-3.0.3 MarkupSafe-2.0.1 Werkzeug-2.0.2 click-8.0.3 itsdangerous-2.0.1 psycopg2-binary-2.9.2
现在您的虚拟环境上已安装所需的包。接下来,您将连接并设置您的数据库。
步驟 3 — 設置資料庫
在此步驟中,您將在您的 flask_app
專案目錄中創建一個 Python 檔案,用於連接到 flask_db
資料庫,創建一個用於存儲書籍的表,並將一些帶有評論的書籍插入其中。
首先,啟動您的程式開發環境,打開一個名為 init_db.py
的新檔案,位於您的 flask_app
目錄中。
此檔案將打開到 flask_db
資料庫的連接,創建一個名為 books
的表,並使用範例數據填充表。將以下代碼添加到其中:
保存並關閉該檔案。
在此檔案中,您首先導入您將使用的 os
模組,以訪問環境變數,您將在其中存儲您的資料庫用戶名和密碼,以便它們不會在您的源代碼中可見。
你导入psycopg2
库。然后使用psycopg2.connect()
函数打开到flask_db
数据库的连接。你指定主机,这里是本地主机。你将数据库名称传递给database
参数。
你通过os.environ
对象提供你的用户名和密码,这个对象可以访问你在编程环境中设置的环境变量。你将数据库用户名存储在名为DB_USERNAME
的环境变量中,将密码存储在名为DB_PASSWORD
的环境变量中。这样可以让你在源代码之外存储用户名和密码,以防止在源代码保存在源代码控制或上传到互联网服务器时泄露你的敏感信息。即使攻击者获得了你的源代码,他们也无法访问数据库。
你使用connection.cursor()
方法创建一个名为cur
的游标,这允许Python代码在数据库会话中执行PostgreSQL命令。
您使用游標的execute()
方法來刪除books
表格,如果它已經存在。這樣可以避免另一個名為books
的表格存在,這可能導致混亂的行為(例如,如果它具有不同的列)。這裡不適用這種情況,因為您尚未創建該表格,所以不會執行SQL命令。請注意,每次執行此init_db.py
文件時,將刪除所有現有數據。對於我們的目的,您只會執行此文件一次來初始化數據庫,但您可能希望再次執行它來刪除您插入的任何數據並重新開始使用最初的樣本數據。
然後您使用CREATE TABLE books
來創建一個名為books
的表格,其中包含以下列:
id
:一個serial
類型的ID,這是一個自動遞增的整數。此列表示您使用PRIMARY KEY
關鍵字指定的主鍵。數據庫將為每個條目分配一個唯一值。title
:書籍的標題,類型為varchar
,這是一種帶有限制的可變長字符類型。varchar (150)
表示標題可以長達150個字符。NOT NULL
表示此列不能為空。author
:書籍的作者,限制為50個字符。NOT NULL
表示此列不能為空。pages_num
:表示書籍頁數的整數。NOT NULL
表示此列不能為空。review
:這是書評。text
類型表示評論可以是任意長度的文本。date_added
:書籍添加到表格中的日期。DEFAULT
將該列的默認值設置為CURRENT_TIMESTAMP
,這是將書籍添加到數據庫的時間。 就像id
一樣,您不需要為此列指定值,因為它將被自動填充。
創建表格後,您使用游標的 execute()
方法將兩本書插入表中,《雙城記》,作者是查爾斯·狄更斯,以及 《安娜·卡列尼娜》,作者是列夫·托爾斯泰。 您使用 %s
佔位符將值傳遞給 SQL 語句。 psycopg2
在後台處理插入,以防止 SQL 注入攻擊。
完成向表中插入書籍數據後,使用 connection.commit()
方法提交事務並將更改應用到數據庫。 然後,通過使用 cur.close()
關閉游標以及使用 conn.close()
關閉連接來清理事務。
為了建立數據庫連接,通過運行以下命令設置 DB_USERNAME
和 DB_PASSWORD
環境變量。 請記住使用您自己的用戶名和密碼:
現在,在終端中使用 python
命令運行您的 init_db.py
文件:
一旦文件完成執行且無錯誤,將會在您的 flask_db
數據庫中添加一個新的 books
表。
登錄到交互式的 Postgres 會話中,查看新的 books
表。
使用 \c
命令連接到 flask_db
數據庫:
然後使用 SELECT
語句從 books
表中獲取書籍的標題和作者:
您將看到如下輸出:
title | author
----------------------+------------------
A Tale of Two Cities | Charles Dickens
Anna Karenina | Leo Tolstoy
使用 \q
退出交互式會話。
接下來,您將創建一個小型的 Flask 應用程序,連接到數據庫,檢索您插入到數據庫中的兩本書的評論,並將它們顯示在主頁上。
步驟 4 — 顯示書籍
在此步驟中,您將創建一個具有索引頁面的 Flask 應用程序,該頁面檢索數據庫中的書籍並顯示它們。
在啟用編程環境並安裝 Flask 後,在您的 flask_app
目錄中打開一個名為 app.py
的文件進行編輯:
此文件將設置您的數據庫連接並創建一個使用該連接的單個 Flask 路由。將以下代碼添加到文件中:
保存並關閉文件。
在這裡,您導入os
模塊,psycopg2
庫,以及flask
包中的Flask
類和render_template()
函數。您創建了一個名為app
的Flask應用程序實例。
您定義了一個名為get_db_connection()
的函數,該函數使用您存儲在DB_USERNAME
和DB_PASSWORD
環境變量中的用戶名和密碼來打開到flask_db
數據庫的連接。該函數返回conn
連接對象,您將使用它來訪問數據庫。
然後,您創建了一個主要的/
路由和一個index()
視圖函數,使用app.route()
裝飾器。在index()
視圖函數中,您使用get_db_connection()
函數打開數據庫連接,創建一個游標,並執行SELECT * FROM books;
的SQL語句,以獲取數據庫中的所有書籍。您使用fetchall()
方法將數據保存在名為books
的變量中。然後,您關閉游標和連接。最後,您返回一個調用render_template()
函數的調用,以渲染一個名為index.html
的模板文件,並將從數據庫中提取的書籍列表作為books
變量傳遞給它。
要在索引页上显示您数据库中的书籍,您首先会创建一个基础模板,该模板将包含所有基本的 HTML 代码,其他模板也将使用它以避免代码重复。然后,您将创建您在 index()
函数中呈现的 index.html
模板文件。要了解更多关于模板的信息,请参见在 Flask 应用程序中使用模板的方法。
创建一个名为 templates
的目录,然后打开一个名为 base.html
的新模板:
在 base.html
文件中添加以下代码:
保存并关闭文件。
此基础模板包含您在其他模板中需要重用的所有 HTML 样板。 title
块将被替换为每个页面的标题,而 content
块将被每个页面的内容替换。 导航栏有两个链接,一个用于索引页面,您可以在其中使用 url_for()
助手函数将其链接到 index()
视图函数,另一个用于您应用程序中可能包含的一个关于页面。
接下来,打开一个名为 index.html
的模板。这是您在 app.py
文件中引用的模板:
向其中添加以下代码:
保存并关闭文件。
在此文件中,您扩展了基础模板,并替换了 content
块的内容。 您使用一个 <h1>
标题,它也充当标题。
你在這一行中使用了一個Jinja迴圈{% for book in books %}
來遍歷books
列表中的每一本書。你顯示了書的ID,即第一個項目,使用book[0]
。然後顯示書的標題、作者、頁數、評論以及書籍添加的日期。
當你位於flask_app
目錄並啟用了你的虛擬環境時,告訴Flask關於應用程序(在這種情況下是app.py
),使用FLASK_APP
環境變量。然後將FLASK_ENV
環境變量設置為development
以在開發模式下運行應用程序並獲得調試器的訪問權限。有關Flask調試器的更多信息,請參見如何處理Flask應用程序中的錯誤。使用以下命令來執行此操作:
請確保如果尚未設置,設置DB_USERNAME
和DB_PASSWORD
環境變量:
接下來,運行應用程序:
在開發服務器運行時,使用瀏覽器訪問以下URL:
http://127.0.0.1:5000/
你將在第一次初始化時看到你添加到數據庫的書籍。
你已經在索引頁面上顯示了數據庫中的書籍。現在,你需要允許用戶添加新書籍。在下一步中,你將添加一個新的路由來添加書籍。
步驟 5 — 新增書籍
在這一步中,您將創建一個新的路由,用於將新書籍和評論添加到數據庫中。
您將添加一個帶有網頁表單的頁面,用戶在其中輸入書籍標題、作者、頁數和書籍評論。
保持開發服務器運行,並打開一個新的終端窗口。
首先,打開您的app.py
文件:
為了處理網頁表單,您需要從flask
包中導入一些內容:
- 全局的
request
對象以訪問提交的數據。 url_for()
函數以生成URL。redirect()
函數以在將書籍添加到數據庫後將用戶重定向到索引頁面。
將這些導入添加到文件的第一行:
然後在app.py
文件的末尾添加以下路由:
保存並關閉文件。
在此路由中,您將元組 ('GET', 'POST')
通過 methods
參數傳遞,以允許 GET 和 POST 請求。GET 請求用於從伺服器檢索數據。POST 請求用於將數據發布到特定路由。默認情況下,僅允許 GET 請求。當用戶首次使用 GET 請求請求 /create
路由時,將呈現名為 create.html
的模板文件。稍後您將編輯此路由以處理用戶填寫並提交添加新書籍的網絡表單的 POST 請求。
打開新的 create.html
模板:
將以下代碼添加到其中:
保存並關閉文件。
您擴展基本模板,設置標題作為標題,並使用 <form>
標記,將屬性 method
設置為 post
以指示表單將提交 POST 請求。
您有一個名為 title
的文本字段,您將在您的 /create
路由中使用它來訪問標題數據。
您有一個用於作者的文本字段,一個用於頁數的數字字段,以及一個用於書評的文本區域。
最後,您在表單末尾有一個 提交 按鈕。
現在,啟動開發伺服器,使用瀏覽器導航到 /create
路由:
http://127.0.0.1:5000/create
您將看到一個 添加新書籍 頁面,其中包含一個用於書籍標題的輸入字段,一個用於其作者的字段,一個用於書籍頁數的字段,一個用於書籍評論的文本區域,以及一個 提交 按鈕。
如果您填寫表格並提交它,向服務器發送一個POST請求,什麼也不會發生,因為您沒有在/create
路由上處理POST請求。
打開app.py
以處理用戶提交的POST請求:
編輯/create
路由如下:
保存並關閉文件。
您在if request.method == 'POST'
條件下處理POST請求。您從request.form
對象中提取標題、作者、頁數和用戶提交的評論。
您使用get_db_connection()
函數打開一個數據庫,並創建一個游標。然後,您執行一個INSERT INTO
SQL語句,將用戶提交的標題、作者、頁數和評論插入到books
表中。
您提交事務,並關閉游標和連接。
最後,您將用戶重定向到索引頁,他們可以在現有書籍下方看到新添加的書籍。
在開發服務器運行時,使用您的瀏覽器導航到/create
路由:
http://127.0.0.1:5000/create
填寫表格並提交。
您將被重定向到索引頁,您將看到您的新書評論。
接下來,您將在導航欄中添加一個到創建頁面的鏈接。打開base.html
:
編輯文件如下:
保存並關閉文件。
在這裡,您可以將一個新的<a>
鏈接添加到導航欄,指向創建頁面。
刷新您的索引頁,您將在導航欄中看到新的鏈接。
現在,您有一個包含網頁表單的頁面,用於添加新的書評。有關網頁表單的更多信息,請參見如何在Flask應用程序中使用Web表單。對於更高級和更安全的管理網頁表單的方法,請參見如何使用Flask-WTF驗證Web表單。
結論
您已經為書評構建了一個小型Web應用程序,該應用程序與PostgreSQL數據庫通信。您的Flask應用程序具有基本的數據庫功能,例如將新數據添加到數據庫中,檢索數據並在頁面上顯示它。
如果您想閱讀更多關於Flask的信息,請查看Flask系列中的其他教程。