- models: 删除 Profile 模型,字段合并到 User;User 新增云朵/公开/收藏计数器;Cloud 新增 favorite_count - schemas/serializers: 展平 UserOut/AuthOut/MeOut/AdminUserOut,移除嵌套 profile - deps: user.profile.role→user.role,移除 selectinload profile - auth/register: 注册时直接设置 user 字段,不再创建 Profile - clouds: 创建/删除云朵时同步 user.cloud_count 计数器,状态变化时同步 public_cloud_count - favorites: 点赞/取消时同步 cloud.favorite_count 计数器 - admin: 审批/隐藏/批量删时同步 public_cloud_count 计数器 - profiles/stats: 用计数器替代实时 COUNT 查询 - alembic: 新增 migration 合并 profiles 到 users,初始化 counters
64 lines
3.3 KiB
Python
64 lines
3.3 KiB
Python
import asyncio
|
|
|
|
from sqlalchemy import select
|
|
from sqlalchemy.orm import selectinload
|
|
|
|
from app.config import settings
|
|
from app.database import SessionLocal
|
|
from app.models import CloudType, User
|
|
from app.security import hash_password, utc_now
|
|
|
|
|
|
CLOUD_TYPES = [
|
|
{"id": 1, "name": "积云", "name_en": "Cumulus", "genus": "低云族", "rarity": "common", "description": "轮廓分明、底部较平,常呈棉花团状的对流云。"},
|
|
{"id": 2, "name": "层云", "name_en": "Stratus", "genus": "低云族", "rarity": "common", "description": "低而均匀的灰色云层,常覆盖大部分天空。"},
|
|
{"id": 3, "name": "卷云", "name_en": "Cirrus", "genus": "高云族", "rarity": "common", "description": "由冰晶组成的纤细白色云丝,常呈羽毛或马尾状。"},
|
|
{"id": 4, "name": "积雨云", "name_en": "Cumulonimbus", "genus": "直展云族", "rarity": "uncommon", "description": "垂直发展旺盛的巨大云体,可能带来雷雨、冰雹和强风。"},
|
|
{"id": 5, "name": "层积云", "name_en": "Stratocumulus", "genus": "低云族", "rarity": "common", "description": "成片或成层排列的低云块,常带有明暗相间的纹理。"},
|
|
{"id": 6, "name": "高积云", "name_en": "Altocumulus", "genus": "中云族", "rarity": "common", "description": "由较小云块组成的中层云,常呈波纹或鱼鳞状。"},
|
|
{"id": 7, "name": "高层云", "name_en": "Altostratus", "genus": "中云族", "rarity": "uncommon", "description": "灰蓝色的中层云幕,太阳通常像隔着毛玻璃一样可见。"},
|
|
{"id": 8, "name": "雨层云", "name_en": "Nimbostratus", "genus": "中低云族", "rarity": "uncommon", "description": "厚而暗的降水云层,常带来持续性的雨或雪。"},
|
|
{"id": 9, "name": "卷层云", "name_en": "Cirrostratus", "genus": "高云族", "rarity": "rare", "description": "薄而透明的冰晶云幕,常在日月周围形成光环。"},
|
|
{"id": 10, "name": "卷积云", "name_en": "Cirrocumulus", "genus": "高云族", "rarity": "rare", "description": "细小白色云粒规则排列形成的高云,俗称鱼鳞天。"},
|
|
]
|
|
|
|
|
|
async def seed() -> None:
|
|
async with SessionLocal() as db:
|
|
for values in CLOUD_TYPES:
|
|
cloud_type = await db.get(CloudType, values["id"])
|
|
if cloud_type:
|
|
for key, value in values.items():
|
|
setattr(cloud_type, key, value)
|
|
else:
|
|
db.add(CloudType(**values))
|
|
|
|
if settings.admin_email and settings.admin_password:
|
|
email = settings.admin_email.strip().lower()
|
|
result = await db.execute(
|
|
select(User).where(User.email == email)
|
|
)
|
|
admin = result.scalar_one_or_none()
|
|
if admin:
|
|
admin.role = "admin"
|
|
admin.is_disabled = False
|
|
admin.email_verified_at = admin.email_verified_at or utc_now()
|
|
else:
|
|
admin = User(
|
|
email=email,
|
|
password_hash=hash_password(settings.admin_password),
|
|
email_verified_at=utc_now(),
|
|
username=settings.admin_username,
|
|
role="admin",
|
|
)
|
|
db.add(admin)
|
|
await db.commit()
|
|
|
|
|
|
def main() -> None:
|
|
asyncio.run(seed())
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|