45 lines
1.9 KiB
Python
45 lines
1.9 KiB
Python
|
||||
|
|
|
|||
|
|
|
|||
|
|
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 = 无论接口成功还是报错,最后一定关闭会话,释放数据库连接
|