baseline: 批次A-D 成果 + membership 半成品(测试红)
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
"""PostgreSQL 测试库准备(一次性)。
|
||||
|
||||
做三件事:
|
||||
1. 探测本机 PostgreSQL 连接(默认 127.0.0.1:5433,用户 postgres);
|
||||
2. 创建 `dealerhub`(开发)与 `dealerhub_test`(测试)两个库(幂等);
|
||||
3. 应用迁移到开发库,使 `DJANGO_SETTINGS_MODULE=config.settings.dev` 能直接连 PG 跑。
|
||||
|
||||
用法:
|
||||
python scripts/setup_pg.py # 用默认凭据探测
|
||||
PG_PORT=5432 PG_USER=me PG_PASSWORD=xx python scripts/setup_pg.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
sys.path.insert(0, str(Path(__file__).resolve().parent.parent))
|
||||
|
||||
PG_HOST = os.environ.get("PG_HOST", "127.0.0.1")
|
||||
PG_PORT = int(os.environ.get("PG_PORT", "5433"))
|
||||
PG_USER = os.environ.get("PG_USER", "postgres")
|
||||
PG_PASSWORD = os.environ.get("PG_PASSWORD", "postgres")
|
||||
|
||||
DEV_DB = os.environ.get("PG_DEV_DB", "dealerhub")
|
||||
TEST_DB = os.environ.get("PG_TEST_DB", "dealerhub_test")
|
||||
|
||||
# 常见本地 PG 密码(只用于"探测",不做暴力破解)
|
||||
PASSWORD_CANDIDATES = [PG_PASSWORD, "", "postgres", "123456", "root", "pg123456", "admin"]
|
||||
|
||||
|
||||
def probe_connection() -> str | None:
|
||||
"""返回可用密码;失败返回 None。"""
|
||||
try:
|
||||
import psycopg
|
||||
except ImportError:
|
||||
print("✗ 未安装 psycopg:pip install 'psycopg[binary]'")
|
||||
return None
|
||||
|
||||
seen = []
|
||||
for pw in PASSWORD_CANDIDATES:
|
||||
if pw in seen:
|
||||
continue
|
||||
seen.append(pw)
|
||||
try:
|
||||
conn = psycopg.connect(
|
||||
host=PG_HOST, port=PG_PORT, user=PG_USER, password=pw,
|
||||
dbname="postgres", connect_timeout=3,
|
||||
)
|
||||
conn.close()
|
||||
return pw
|
||||
except Exception as exc:
|
||||
print(f" · {PG_USER}/{pw or '(空)'} → {str(exc)[:70]}")
|
||||
return None
|
||||
|
||||
|
||||
def ensure_databases(password: str) -> bool:
|
||||
import psycopg
|
||||
|
||||
ok = True
|
||||
conn = psycopg.connect(
|
||||
host=PG_HOST, port=PG_PORT, user=PG_USER, password=password,
|
||||
dbname="postgres", autocommit=True,
|
||||
)
|
||||
cur = conn.cursor()
|
||||
for db in (DEV_DB, TEST_DB):
|
||||
cur.execute("SELECT 1 FROM pg_database WHERE datname = %s", (db,))
|
||||
if cur.fetchone():
|
||||
print(f" · {db} 已存在")
|
||||
else:
|
||||
cur.execute(f'CREATE DATABASE "{db}"')
|
||||
print(f" ✓ 创建 {db}")
|
||||
cur.close()
|
||||
conn.close()
|
||||
return ok
|
||||
|
||||
|
||||
def apply_migrations_to_dev(password: str) -> bool:
|
||||
"""把迁移应用到开发库(让 dev 设置能直接用 PG)。"""
|
||||
os.environ.update({
|
||||
"DATABASE_URL": f"postgres://{PG_USER}:{password}@{PG_HOST}:{PG_PORT}/{DEV_DB}",
|
||||
"DJANGO_SETTINGS_MODULE": "config.settings.dev",
|
||||
})
|
||||
import django
|
||||
|
||||
django.setup()
|
||||
from django.core.management import call_command
|
||||
|
||||
call_command("migrate", "--noinput", verbosity=0)
|
||||
return True
|
||||
|
||||
|
||||
def main() -> int:
|
||||
print(f"探测 PostgreSQL · {PG_HOST}:{PG_PORT} · user={PG_USER}")
|
||||
pw = probe_connection()
|
||||
if pw is None:
|
||||
print("\n✗ 无法连接。请确认:")
|
||||
print(" 1. PostgreSQL 服务已启动")
|
||||
print(" 2. 端口正确(PG_PORT=5433 是本机 PG 16 的常见端口)")
|
||||
print(" 3. 凭据正确(PG_USER / PG_PASSWORD)")
|
||||
return 1
|
||||
print(f" ✓ 连接成功(密码:{pw or '(空)'})")
|
||||
|
||||
print("\n创建数据库")
|
||||
ensure_databases(pw)
|
||||
|
||||
print("\n应用迁移到开发库")
|
||||
apply_migrations_to_dev(pw)
|
||||
print(f" ✓ {DEV_DB} 迁移完成")
|
||||
|
||||
print(f"""
|
||||
准备完成。运行方式:
|
||||
|
||||
# 开发/手工验证(连 PG)
|
||||
export DATABASE_URL="postgres://{PG_USER}:{pw}@{PG_HOST}:{PG_PORT}/{DEV_DB}"
|
||||
DJANGO_SETTINGS_MODULE=config.settings.dev granian config.asgi:application --interface asgi --port 8000
|
||||
|
||||
# 全量测试(含并发,PG 行锁语义)
|
||||
DJANGO_SETTINGS_MODULE=config.settings.pgtest python -m pytest tests/ -p no:cacheprovider
|
||||
|
||||
# 只跑并发用例
|
||||
DJANGO_SETTINGS_MODULE=config.settings.pgtest python -m pytest tests/test_concurrency.py -p no:cacheprovider -m postgres
|
||||
""")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Reference in New Issue
Block a user