Files
crm_project/server/alembic/env.py
T
hankin 423baff73b v0.1.0: CRM/ERP 系统内测版本 - 安全加固完成
- Docker bridge 网络隔离(8000 端口封死)
- Gunicorn 4 Worker 多进程
- Alembic 数据库迁移基线
- 日志轮转 20m×3
- JWT 密钥 + DB 密码 + CORS 收紧
- 3-2-1 备份链路(NAS + R740-B 冷备)
- 连接池 pool_pre_ping + pool_recycle=3600
2026-03-16 07:31:37 +00:00

94 lines
2.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Alembic env.py — 异步 PostgreSQL 迁移环境
从 .env 读取 DATABASE_URL,自动发现项目所有 ORM 模型
"""
import asyncio
import os
import sys
from logging.config import fileConfig
from alembic import context
from dotenv import load_dotenv
from sqlalchemy import pool
from sqlalchemy.ext.asyncio import async_engine_from_config
# 确保项目根目录在 sys.path 中
sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
# 加载 .env
load_dotenv(os.path.join(os.path.dirname(os.path.dirname(__file__)), ".env"))
# Alembic Config
config = context.config
# 从 .env 动态设置 sqlalchemy.urlasyncpg → psycopg2 用于迁移)
db_url = os.getenv("DATABASE_URL", "")
# Alembic 需要同步驱动,将 asyncpg 替换为 psycopg2
sync_url = db_url.replace("+asyncpg", "")
config.set_main_option("sqlalchemy.url", sync_url)
# 日志配置
if config.config_file_name is not None:
fileConfig(config.config_file_name)
# 导入所有模型,确保 Alembic 能检测到所有表
from app.models.base import Base
from app.models import crm, erp, order, shipping, finance, ai, sys as sys_models
target_metadata = Base.metadata
def run_migrations_offline() -> None:
"""离线迁移(仅生成 SQL 脚本)"""
url = config.get_main_option("sqlalchemy.url")
context.configure(
url=url,
target_metadata=target_metadata,
literal_binds=True,
dialect_opts={"paramstyle": "named"},
)
with context.begin_transaction():
context.run_migrations()
def do_run_migrations(connection):
context.configure(connection=connection, target_metadata=target_metadata)
with context.begin_transaction():
context.run_migrations()
async def run_async_migrations():
"""在线迁移(异步引擎)"""
from sqlalchemy.ext.asyncio import create_async_engine
connectable = create_async_engine(
os.getenv("DATABASE_URL", ""),
poolclass=pool.NullPool,
)
async with connectable.connect() as connection:
await connection.run_sync(do_run_migrations)
await connectable.dispose()
def run_migrations_online() -> None:
"""在线迁移入口"""
# 如果是 asyncpg 则走异步迁移
db_url = os.getenv("DATABASE_URL", "")
if "asyncpg" in db_url:
asyncio.run(run_async_migrations())
else:
from sqlalchemy import engine_from_config
connectable = engine_from_config(
config.get_section(config.config_ini_section, {}),
prefix="sqlalchemy.",
poolclass=pool.NullPool,
)
with connectable.connect() as connection:
do_run_migrations(connection)
if context.is_offline_mode():
run_migrations_offline()
else:
run_migrations_online()