Files
sqlalchemy_fastapi_demo_1/database.py
T

45 lines
1.9 KiB
Python
Raw Normal View History

2026-09-21 19:15:28 +08:00
import os
from urllib.parse import quote_plus
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker, declarative_base
# 导入"会话工厂"和"ORM基类"
# 数据库连接信息:优先读环境变量,读不到才用括号里的默认值(本地直接跑不用改代码)
# 部署到 Docker / 服务器时,只改环境变量即可,不需要动源码
DB_USER = os.getenv("MYSQL_USER", "root")
DB_PASSWORD = os.getenv("MYSQL_PASSWORD", "123456")
DB_HOST = os.getenv("MYSQL_HOST", "localhost")
DB_PORT = os.getenv("MYSQL_PORT", "3306")
DB_NAME = os.getenv("MYSQL_NAME", "sys")
# 也可以直接给一个完整的 DATABASE_URL,优先级最高
# 例:mysql+pymysql://root:123456@host.docker.internal:3306/0914tw?charset=utf8mb4
# quote_plus 用于转义密码里可能出现的 @ # / 等特殊字符
SQLALCHEMY_DATABASE_URL = os.getenv("DATABASE_URL") or (
f"mysql+pymysql://{DB_USER}:{quote_plus(DB_PASSWORD)}"
f"@{DB_HOST}:{DB_PORT}/{DB_NAME}?charset=utf8mb4"
)
# ===============================================
# pool_pre_ping=True:每次取连接前先探活,容器/网络断开重连时不会拿到死连接
engine = create_engine(SQLALCHEMY_DATABASE_URL, pool_pre_ping=True)
# 创建"引擎":引擎负责真正和MySQL建立连接、执行SQL。整个项目共用这一个引擎。
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
#创建ORM基类:后面所有表模型(Classinfo等)都要继承Base,SQLAlchemy才知道它们是数据库表
# 提供数据库会话,接口通过 Depends(get_db) 自动获取
def get_db():
db = SessionLocal() # 创建一个新的数据库会话
try:
yield db # yield = 把会话"借出去"给接口函数用(执行到这里暂停,等接口用完)
finally:
db.close() # finally = 无论接口成功还是报错,最后一定关闭会话,释放数据库连接