FastAPI 快速開發(fā) Web API 項(xiàng)目: 通過 SQLAlchemy 進(jìn)行數(shù)據(jù)操作
介紹
FastAPI 不要求我們強(qiáng)制使用 SQL(關(guān)系)數(shù)據(jù)庫。因此,我們可以根據(jù)需求使用任何關(guān)系數(shù)據(jù)庫,例如:
- PostgreSQL
- MySQL
- SQLite
- 神諭
- 微軟SQL Server
- ...
這篇文章以 MySQL 為例,首先需要為 MySQL 安裝 Python 庫,F(xiàn)astAPI 需要使用 Python 的 MySQL 客戶端庫來連接到 MySQL 數(shù)據(jù)庫,這些驅(qū)動(dòng)包括 和 。mysql-connector-pythonpymysql
安裝這些庫:
pip install mysql-connector-python pymysql
安裝成功如圖所示:
用于定義 FastAPI 依賴項(xiàng)的 Python 文件名沒有特定的命名約定。通常,最好使用與應(yīng)用程序的功能和角色匹配的名稱命名,包含定義 FastAPI 依賴項(xiàng)的函數(shù)的 Python 文件。
在終端中,運(yùn)行以下命令以在 MySQL 數(shù)據(jù)庫中創(chuàng)建數(shù)據(jù)庫 :example_db
//Login to MySQL
mysql -u root -p
//Create database named example_db
CREATE DATABASE example_db;
創(chuàng)建數(shù)據(jù)庫表 :users
CREATE TABLE
`users` (
`id` int unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb3
往數(shù)據(jù)庫表中插入一條數(shù)據(jù):
INSERT INTO users (name) VALUES ("Atom");
db.py 文件
例如,通常命名一個(gè)包含依賴項(xiàng)函數(shù)的 Python 文件,該函數(shù)定義與上面示例中所示的 MySQL 數(shù)據(jù)庫的連接,以指示它具有與數(shù)據(jù)庫相關(guān)的功能,例如 或 。db.pydatabase.py
此外,如果您有多個(gè)定義 FastAPI 依賴項(xiàng)的函數(shù),或者如果您為不同功能定義了依賴項(xiàng),則可以通過為每個(gè)功能指定不同的名稱來提高代碼的可讀性。
例如,請(qǐng)考慮以下文件名:
- db.py:包含定義與 MySQL 數(shù)據(jù)庫連接的依賴項(xiàng)的文件。
- auth.py:定義與身份驗(yàn)證相關(guān)的依賴項(xiàng)的文件。
- validation.py:定義驗(yàn)證輸入數(shù)據(jù)的依賴項(xiàng)的文件。
根據(jù)項(xiàng)目的大小和結(jié)構(gòu),您還可以設(shè)計(jì)目錄和模塊的層次結(jié)構(gòu)。通過將包含定義依賴項(xiàng)的函數(shù)的 Python 文件放置在適當(dāng)?shù)哪夸浿胁⑺鼈兘M織為模塊,可以改進(jìn)代碼管理和可維護(hù)性。
將 MySQL 客戶端庫添加到 FastAPI 依賴項(xiàng):使用 FastAPI 依賴項(xiàng)將 MySQL 客戶端庫添加到您的應(yīng)用程序。例如,如果使用 ,請(qǐng)按如下方式添加依賴項(xiàng):mysql-connector-python
$ touch routers/db.py
然后在 中寫入如下代碼:db.py
from fastapi import Depends
import mysql.connector
def get_db_connection():
connection = mysql.connector.connect(
host='localhost',
port=3306,
user="root",
password="123456",
database="example_db"
)
return connection
def get_db():
connection = get_db_connection()
db = connection.cursor()
try:
yield db
finally:
db.close()
connection.close()
db_router 文件
在路由器上使用 MySQL 數(shù)據(jù)庫:要將 MySQL 數(shù)據(jù)庫與 FastAPI 的路由器一起使用,請(qǐng)使用上面定義的 函數(shù)作為依賴項(xiàng)。下面是在 FastAPI 的路由器中使用 MySQL 數(shù)據(jù)庫的示例。get_db()
在將 MySQL 數(shù)據(jù)庫與 FastAPI 路由器一起使用的示例 Python 文件名中,通常最好根據(jù)應(yīng)用程序的功能和角色對(duì)其進(jìn)行命名。你可以想到這樣的文件名:
- main.py:包含示例代碼的文件,該示例是應(yīng)用程序的主要入口點(diǎn),定義 FastAPI 路由器并使用 MySQL 數(shù)據(jù)庫。
- router.py:定義 FastAPI 路由器并包含使用 MySQL 數(shù)據(jù)庫的示例的代碼的文件。
- db.py:包含用于連接和查詢 MySQL 數(shù)據(jù)庫的函數(shù)的文件。
根據(jù)項(xiàng)目的大小和結(jié)構(gòu),您還可以設(shè)計(jì)目錄和模塊的層次結(jié)構(gòu)。例如,您可以通過創(chuàng)建名為路由器的目錄,在其中創(chuàng)建定義 FastAPI 路由器的模塊,并在其中包含使用 MySQL 數(shù)據(jù)庫的示例代碼來提高代碼組織和可讀性。
例如,可以考慮以下文件名和目錄結(jié)構(gòu):
- main.py:作為應(yīng)用程序主入口點(diǎn)的文件,導(dǎo)入并使用路由器目錄中的路由器模塊。
- routers/db_router.py:定義使用 MySQL 數(shù)據(jù)庫的示例路由器的模塊。
- routers/db.py:定義用于連接和查詢MySQL數(shù)據(jù)庫的函數(shù)的模塊。
db_router.py文件寫入如下內(nèi)容:
from fastapi import FastAPI, Depends
from mysql.connector import cursor
from db import get_db
import json
app = FastAPI()
# def get_db(db: cursor.MySQLCursor = Depends(get_db)):
# return db
@app.get("/users/")
async def get_users(db: cursor.MySQLCursor = Depends(get_db)):
query = "SELECT * FROM users"
db.execute(query)
result = db.fetchall()
if result:
return {"users": result}
else:
return {"error": "User not found"}
@app.get("/users/{user_id}")
async def get_user(user_id: int,
db: cursor.MySQLCursor = Depends(get_db)):
query = "SELECT * FROM users WHERE id = %s"
db.execute(query, (user_id,))
result = db.fetchall()
if result:
return {"user_id": result[0][0], "username": result[0][1]}
else:
return {"error": "User not found"}
@app.get("/user_name/{user_name}")
async def insert_user(user_name: str,
db: cursor.MySQLCursor = Depends(get_db)):
query = "INSERT INTO users (name) VALUES (%s)"
db.execute(query, (user_name,))
result = db.fetchone()
db.execute("COMMIT")
return {"user_name": user_name}
啟動(dòng) FastAPI 服務(wù)
uvicorn db_router:app --reload
INFO: Will watch for changes in these directories: ['/Users/sharland/dev/fastapi/MySQL/routers']
INFO: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
INFO: Started reloader process [60501] using WatchFiles
INFO: Started server process [60503]
INFO: Waiting for application startup.
INFO: Application startup complete.
當(dāng)您在瀏覽器中訪問 http://127.0.0.1:8000/docs 時(shí),將顯示一個(gè)屏幕,允許您使用 GUI 操作快速 API 服務(wù)。
訪問 ,可以獲取當(dāng)前數(shù)據(jù)庫中的所有用戶數(shù)據(jù):http://127.0.0.1:8000/users/
"users":[[1,"Atom","2023-04-20T13:14:00"],[2,"Nuoza","2023-04-20T13:14:20"]]}
當(dāng)訪問 時(shí),結(jié)果:http://127.0.0.1:8000/users/1
{"user_id":1,"username":"Atom"}
新增一個(gè)用戶,。操作如圖:http://127.0.0.1:8000/user_name/Dole
總結(jié)
本文總結(jié)了通過 MySQL 驅(qū)動(dòng)連接 Python, 實(shí)現(xiàn)了一個(gè) FastAPI 連接 MySQL 數(shù)據(jù)庫的示例, 并結(jié)合代碼結(jié)構(gòu)設(shè)計(jì)了目錄結(jié)構(gòu)和實(shí)現(xiàn)了獲取用戶和增加用戶的功能,但是本文只是簡(jiǎn)單使用了原生的 MySQL,其實(shí) FastAPI 支持結(jié)合 SQLAlchemy 更方面創(chuàng)建模型的數(shù)據(jù)庫語句,今后會(huì)繼續(xù)沿用這個(gè)示例寫用戶的登錄和注冊(cè)功能, 敬請(qǐng)期待。