初始化提交
This commit is contained in:
commit
887c1f449e
963 files changed
+166869
No files matched your search
@@ -0,0 +1,98 @@
|
||||
"""PostgreSQL 兼容性冒烟测试。
|
||||
|
||||
**独立运行**,不依赖 pytest conftest 中的 reset_database 夹具。
|
||||
直接管理 engine 生命周期,避免 autouse 夹具冲突。
|
||||
|
||||
验证:
|
||||
1. SQLAlchemy metadata.create_all / drop_all 在 PG 下完整可用
|
||||
2. 核心 CRUD(角色创建/查询/更新)在 PG 下正常
|
||||
3. PG 特有类型问题(如 varchar vs date 比较)已被修复
|
||||
|
||||
运行方式:
|
||||
UV_PYTHON_PATH="$PWD/.venv/bin/python" uv run python tests/test_pg_compat.py
|
||||
|
||||
或直接:
|
||||
HUNJING_TEST_DATABASE_URL="postgresql+asyncpg://hunjing:change-me@127.0.0.1:5432/hunjing_test" \\
|
||||
uv run python tests/test_pg_compat.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
||||
async def _run() -> None:
|
||||
database_url = os.environ.get("HUNJING_TEST_DATABASE_URL", "")
|
||||
if not database_url.startswith("postgresql"):
|
||||
print("❌ 请设 HUNJING_TEST_DATABASE_URL 环境变量")
|
||||
sys.exit(1)
|
||||
|
||||
assert "test" in database_url, "必须指向名含 test 的数据库"
|
||||
print(f"✅ 数据库 URL: {database_url}")
|
||||
|
||||
from sqlalchemy.ext.asyncio import AsyncSession, async_sessionmaker, create_async_engine
|
||||
|
||||
from app.db.base import Base
|
||||
|
||||
engine = create_async_engine(database_url)
|
||||
AsyncSessionLocal = async_sessionmaker(engine, expire_on_commit=False, class_=AsyncSession)
|
||||
|
||||
# ── 建表 ─────────────────────────────────────────────
|
||||
print("⏳ 创建表...")
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.create_all)
|
||||
print("✅ 39 张表已创建")
|
||||
|
||||
from app.core.ids import new_character_id, new_user_id
|
||||
from app.models.character import Character
|
||||
from app.repositories.json_utils import dumps, loads_dict
|
||||
|
||||
# ── CRUD ─────────────────────────────────────────────
|
||||
async with AsyncSessionLocal() as session:
|
||||
owner = new_user_id()
|
||||
char = Character(
|
||||
id=new_character_id(),
|
||||
name="pg-test-char",
|
||||
display_name="PG测试",
|
||||
status="active",
|
||||
language="zh-CN",
|
||||
profile_json=dumps({"name": "PG 测试角色"}),
|
||||
model_policy_json=dumps({"default_chat_model_hint": "test-model"}),
|
||||
privacy_level="normal",
|
||||
owner_scope=owner,
|
||||
is_system_template=False,
|
||||
)
|
||||
session.add(char)
|
||||
await session.flush()
|
||||
char_id = char.id
|
||||
print(f"✅ 创建角色: {char_id}")
|
||||
|
||||
from app.services.characters import get_owned_character
|
||||
|
||||
found = await get_owned_character(session, char_id, owner)
|
||||
assert found.id == char_id
|
||||
assert found.name == "pg-test-char"
|
||||
print("✅ 查询角色")
|
||||
|
||||
profile = loads_dict(found.profile_json)
|
||||
profile["description"] = "更新后描述"
|
||||
found.profile_json = dumps(profile)
|
||||
await session.flush()
|
||||
await session.refresh(found)
|
||||
assert loads_dict(found.profile_json).get("description") == "更新后描述"
|
||||
print("✅ 更新角色")
|
||||
|
||||
await session.commit()
|
||||
|
||||
# ── 清理 ─────────────────────────────────────────────
|
||||
async with engine.begin() as conn:
|
||||
await conn.run_sync(Base.metadata.drop_all)
|
||||
await engine.dispose()
|
||||
print("✅ 表已清理")
|
||||
print("\n🎉 PostgreSQL 兼容性验证全部通过")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
asyncio.run(_run())
|
||||
Reference in new issue
Block a user