227 lines
6.9 KiB
Python
227 lines
6.9 KiB
Python
|
|
#!/usr/bin/env python3
|
|||
|
|
"""
|
|||
|
|
补全多恒星系统数据并启用恒星和行星
|
|||
|
|
参考比邻星系统(Alpha Centauri)的数据结构
|
|||
|
|
"""
|
|||
|
|
import asyncio
|
|||
|
|
import asyncpg
|
|||
|
|
import json
|
|||
|
|
import logging
|
|||
|
|
from datetime import datetime
|
|||
|
|
|
|||
|
|
logging.basicConfig(level=logging.INFO)
|
|||
|
|
logger = logging.getLogger(__name__)
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 数据库连接配置
|
|||
|
|
DB_CONFIG = {
|
|||
|
|
"host": "localhost",
|
|||
|
|
"port": 5432,
|
|||
|
|
"user": "postgres",
|
|||
|
|
"password": "postgres",
|
|||
|
|
"database": "cosmo_db"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
# 已知的多恒星系统数据(来自天文学资料)
|
|||
|
|
MULTI_STAR_SYSTEMS = {
|
|||
|
|
# Alpha Centauri System (比邻星系统) - system_id = 479
|
|||
|
|
479: {
|
|||
|
|
"stars": [
|
|||
|
|
{
|
|||
|
|
"id": "star-479-primary",
|
|||
|
|
"name": "Alpha Centauri A",
|
|||
|
|
"name_zh": "南门二A",
|
|||
|
|
"description": "该恒星系主序星,光谱类型: G2V, 表面温度: 5790K",
|
|||
|
|
"extra_data": {
|
|||
|
|
"spectral_type": "G2V",
|
|||
|
|
"mass_solar": 1.1,
|
|||
|
|
"radius_solar": 1.22,
|
|||
|
|
"temperature_k": 5790
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "star-479-secondary",
|
|||
|
|
"name": "Alpha Centauri B",
|
|||
|
|
"name_zh": "南门二B",
|
|||
|
|
"description": "与南门二A相互绕转的明亮双星,是该系统的主体。",
|
|||
|
|
"extra_data": {
|
|||
|
|
"spectral_type": "K1V",
|
|||
|
|
"mass_solar": 0.93,
|
|||
|
|
"radius_solar": 0.86,
|
|||
|
|
"temperature_k": 5260
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
{
|
|||
|
|
"id": "star-479-tertiary",
|
|||
|
|
"name": "Proxima Centauri",
|
|||
|
|
"name_zh": "比邻星",
|
|||
|
|
"description": "一颗质量小、光度弱的红矮星,距离南门二A/B约0.2光年,围绕它们公转。",
|
|||
|
|
"extra_data": {
|
|||
|
|
"spectral_type": "M5.5V",
|
|||
|
|
"mass_solar": 0.12,
|
|||
|
|
"radius_solar": 0.14,
|
|||
|
|
"temperature_k": 2900
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def check_existing_data(conn):
|
|||
|
|
"""检查现有数据"""
|
|||
|
|
logger.info("=== 检查现有数据 ===")
|
|||
|
|
|
|||
|
|
# 检查恒星系统
|
|||
|
|
rows = await conn.fetch("""
|
|||
|
|
SELECT id, name, name_zh, host_star_name, planet_count
|
|||
|
|
FROM star_systems
|
|||
|
|
WHERE id IN (479, 2, 3, 4, 5)
|
|||
|
|
ORDER BY id
|
|||
|
|
""")
|
|||
|
|
|
|||
|
|
print("\n恒星系统:")
|
|||
|
|
for row in rows:
|
|||
|
|
print(f" ID={row['id']}: {row['name_zh'] or row['name']} (主恒星: {row['host_star_name']}, 行星数: {row['planet_count']})")
|
|||
|
|
|
|||
|
|
# 检查比邻星系统的天体
|
|||
|
|
rows = await conn.fetch("""
|
|||
|
|
SELECT id, name, name_zh, type, is_active
|
|||
|
|
FROM celestial_bodies
|
|||
|
|
WHERE system_id = 479
|
|||
|
|
ORDER BY type, name
|
|||
|
|
""")
|
|||
|
|
|
|||
|
|
print("\n比邻星系统(479)的天体:")
|
|||
|
|
for row in rows:
|
|||
|
|
print(f" {row['type']:15} | {row['name']:30} | Active: {row['is_active']}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def add_missing_stars(conn):
|
|||
|
|
"""添加缺失的恒星"""
|
|||
|
|
logger.info("\n=== 添加缺失的恒星 ===")
|
|||
|
|
|
|||
|
|
for system_id, system_data in MULTI_STAR_SYSTEMS.items():
|
|||
|
|
logger.info(f"\n处理恒星系统 ID={system_id}")
|
|||
|
|
|
|||
|
|
for star in system_data["stars"]:
|
|||
|
|
# 检查是否已存在
|
|||
|
|
existing = await conn.fetchrow(
|
|||
|
|
"SELECT id FROM celestial_bodies WHERE id = $1",
|
|||
|
|
star["id"]
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if existing:
|
|||
|
|
logger.info(f" ✓ 恒星已存在: {star['name']} ({star['id']})")
|
|||
|
|
else:
|
|||
|
|
# 插入新恒星
|
|||
|
|
await conn.execute("""
|
|||
|
|
INSERT INTO celestial_bodies
|
|||
|
|
(id, name, name_zh, type, system_id, description, is_active, extra_data, created_at, updated_at)
|
|||
|
|
VALUES
|
|||
|
|
($1, $2, $3, 'star', $4, $5, TRUE, $6::jsonb, NOW(), NOW())
|
|||
|
|
""",
|
|||
|
|
star["id"],
|
|||
|
|
star["name"],
|
|||
|
|
star["name_zh"],
|
|||
|
|
system_id,
|
|||
|
|
star["description"],
|
|||
|
|
json.dumps(star["extra_data"])
|
|||
|
|
)
|
|||
|
|
logger.info(f" ✅ 添加恒星: {star['name_zh']} ({star['id']})")
|
|||
|
|
|
|||
|
|
logger.info("\n恒星数据补全完成!")
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def activate_stars_and_planets(conn):
|
|||
|
|
"""启用所有恒星和行星"""
|
|||
|
|
logger.info("\n=== 启用恒星和行星 ===")
|
|||
|
|
|
|||
|
|
# 启用所有恒星(除了太阳系之外的其他系统)
|
|||
|
|
stars = await conn.fetch("""
|
|||
|
|
UPDATE celestial_bodies
|
|||
|
|
SET is_active = TRUE, updated_at = NOW()
|
|||
|
|
WHERE type = 'star' AND system_id > 1
|
|||
|
|
RETURNING id, name, name_zh
|
|||
|
|
""")
|
|||
|
|
|
|||
|
|
logger.info(f"\n启用了 {len(stars)} 颗恒星:")
|
|||
|
|
for star in stars:
|
|||
|
|
logger.info(f" ✓ {star['name_zh'] or star['name']} ({star['id']})")
|
|||
|
|
|
|||
|
|
# 启用所有行星(除了太阳系之外的其他系统)
|
|||
|
|
planets = await conn.fetch("""
|
|||
|
|
UPDATE celestial_bodies
|
|||
|
|
SET is_active = TRUE, updated_at = NOW()
|
|||
|
|
WHERE type = 'planet' AND system_id > 1
|
|||
|
|
RETURNING id, name, name_zh
|
|||
|
|
""")
|
|||
|
|
|
|||
|
|
logger.info(f"\n启用了 {len(planets)} 颗行星:")
|
|||
|
|
for planet in planets:
|
|||
|
|
logger.info(f" ✓ {planet['name_zh'] or planet['name']} ({planet['id']})")
|
|||
|
|
|
|||
|
|
logger.info("\n启用完成!")
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def verify_results(conn):
|
|||
|
|
"""验证结果"""
|
|||
|
|
logger.info("\n=== 验证结果 ===")
|
|||
|
|
|
|||
|
|
# 统计各系统的天体数量
|
|||
|
|
rows = await conn.fetch("""
|
|||
|
|
SELECT
|
|||
|
|
s.id,
|
|||
|
|
s.name,
|
|||
|
|
s.name_zh,
|
|||
|
|
COUNT(CASE WHEN cb.type = 'star' THEN 1 END) as star_count,
|
|||
|
|
COUNT(CASE WHEN cb.type = 'planet' THEN 1 END) as planet_count,
|
|||
|
|
COUNT(CASE WHEN cb.is_active = TRUE THEN 1 END) as active_count
|
|||
|
|
FROM star_systems s
|
|||
|
|
LEFT JOIN celestial_bodies cb ON s.id = cb.system_id
|
|||
|
|
WHERE s.id IN (479, 2, 3, 4, 5, 6, 7, 8, 9, 10)
|
|||
|
|
GROUP BY s.id, s.name, s.name_zh
|
|||
|
|
ORDER BY s.id
|
|||
|
|
""")
|
|||
|
|
|
|||
|
|
print("\n各恒星系统统计:")
|
|||
|
|
print(f"{'系统ID':<8} {'名称':<30} {'恒星数':<8} {'行星数':<8} {'启用数':<8}")
|
|||
|
|
print("-" * 80)
|
|||
|
|
for row in rows:
|
|||
|
|
print(f"{row['id']:<8} {(row['name_zh'] or row['name']):<30} {row['star_count']:<8} {row['planet_count']:<8} {row['active_count']:<8}")
|
|||
|
|
|
|||
|
|
|
|||
|
|
async def main():
|
|||
|
|
"""主函数"""
|
|||
|
|
print("=" * 80)
|
|||
|
|
print("多恒星系统数据补全和启用脚本")
|
|||
|
|
print("=" * 80)
|
|||
|
|
|
|||
|
|
# 连接数据库
|
|||
|
|
conn = await asyncpg.connect(**DB_CONFIG)
|
|||
|
|
|
|||
|
|
try:
|
|||
|
|
# 1. 检查现有数据
|
|||
|
|
await check_existing_data(conn)
|
|||
|
|
|
|||
|
|
# 2. 添加缺失的恒星
|
|||
|
|
await add_missing_stars(conn)
|
|||
|
|
|
|||
|
|
# 3. 启用恒星和行星
|
|||
|
|
await activate_stars_and_planets(conn)
|
|||
|
|
|
|||
|
|
# 4. 验证结果
|
|||
|
|
await verify_results(conn)
|
|||
|
|
|
|||
|
|
print("\n" + "=" * 80)
|
|||
|
|
print("✅ 所有操作完成!")
|
|||
|
|
print("=" * 80)
|
|||
|
|
|
|||
|
|
finally:
|
|||
|
|
await conn.close()
|
|||
|
|
|
|||
|
|
|
|||
|
|
if __name__ == "__main__":
|
|||
|
|
asyncio.run(main())
|