"""Create the wanfa category and route domain. Revision ID: 0015_wanfa Revises: 0001_initial_schema """ from datetime import datetime from alembic import context, op import sqlalchemy as sa from sqlalchemy import inspect revision = "0015_wanfa" down_revision = "0001_initial_schema" branch_labels = None depends_on = None SEED_CATEGORIES = ( ("family-route", "亲子路线", 0), ("photo-route", "旅拍路线", 1), ("healing-route", "疗愈路线", 2), ("team-building", "团建", 3), ("guizhou-panorama", "贵州全景", 4), ("private-custom", "私人定制", 5), ) SEED_ROUTES = ( ("family-water", "family-route", "亲子玩水", "贵州·轻松节奏与自然课堂", "https://p0.51img.ca/i/669740a019b94.jpeg", 4, "亲子玩水", 0), ("family-village", "family-route", "亲子村寨漫游", "贵州·苗寨、古城与在地体验", "https://p6.itc.cn/q_70/images03/20200918/df728d2b79d943da869333e2ea2c92c8.jpeg", 3, "亲子村寨漫游", 1), ("family-grassland", "family-route", "高原亲子假期", "贵州·草甸、花海与轻徒步", "https://p2.cri.cn/M00/89/21/rBABC2aHnWeACxj5AAAAAAAAAAA159.1000x566.jpg", 2, "高原亲子假期", 2), ("miao-photo", "photo-route", "苗寨人文旅拍", "黔东南·村寨与非遗影像", "https://i.pinimg.com/736x/d5/86/5d/d5865d0b2765dfb6713787aede09f086.jpg", 3, "苗寨旅拍", 0), ("peak-photo", "photo-route", "峰林风光旅拍", "黔西南·峰林与峡谷取景", "https://wanfenglin-guanwang.oss-cn-chengdu.aliyuncs.com/uploads/20240718/23ea4291a9570b94a1f8df9a012c18ec.jpg", 2, "万峰林旅拍", 1), ("terrace-photo", "photo-route", "梯田日落旅拍", "黔东南·侗寨与山野光影", "https://news.cgtn.com/news/2023-08-28/Spectacular-rice-terraces-in-Guizhou-1mDHGG4vtHq/img/9ff1dc49c6304b35bdb83bc1f7f8df93/9ff1dc49c6304b35bdb83bc1f7f8df93.jpeg", 2, "梯田旅拍", 2), ("mountain-healing", "healing-route", "山野慢游", "贵州·森林、溪谷与松弛时光", "https://images.unsplash.com/photo-1501785888041-af3ef285b470?auto=format&fit=crop&fm=jpg&q=80&w=1200&h=800", 3, "山野慢游", 0), ("hot-spring-healing", "healing-route", "温泉与村寨", "黔东南·泡汤、慢行与在地风味", "https://www.gz007.net/images/upload/jianhewenquan2.jpg", 2, "温泉与村寨", 1), ("river-healing", "healing-route", "清凉河谷", "荔波·水线轻徒步与自然疗愈", "https://p0.51img.ca/i/669740a019b94.jpeg", 3, "清凉河谷", 2), ("team-challenge", "team-building", "山野挑战", "贵州·峡谷协作与户外任务", "https://q9.itc.cn/q_70/images03/20250810/b62f5afc191a4947a66e6b32721b0235.jpeg", 3, "山野挑战", 0), ("team-stream", "team-building", "溪谷共创", "贵州·溯溪、协作与团队复盘", "https://dimg04.c-ctrip.com/images/0EQ5712000ca7t504EC0E_W_640_10000.jpg?proc=autoorient", 2, "溪谷共创", 1), ("team-culture", "team-building", "苗寨共聚", "黔东南·人文体验与团队共创", "https://news.cgtn.com/news/2023-07-13/Miao-people-celebrate-Canoe-Dragon-Boat-Festival-1lpanidzxu0/img/61b7100caa8a441aacb3780cfa3eeb69/61b7100caa8a441aacb3780cfa3eeb69.jpeg", 2, "苗寨共聚", 2), ("classic-panorama", "guizhou-panorama", "经典贵州全景", "贵州·瀑布、苗寨、古城与梵净山", "https://news.cgtn.com/news/2023-07-02/Picturesque-landscapes-draw-tourists-to-Guizhou--1l6RJMNVStq/img/f0d32df3426e4b70bf7a8b00a3404ef9/f0d32df3426e4b70bf7a8b00a3404ef9.jpeg", 8, "经典人文打卡线路", 0), ("mountain-panorama", "guizhou-panorama", "山水人文全景", "贵州·小七孔、侗寨与山地风光", "https://p6.itc.cn/q_70/images03/20200918/df728d2b79d943da869333e2ea2c92c8.jpeg", 6, "贵州全景", 1), ("wild-panorama", "guizhou-panorama", "山野户外全景", "贵州·溶洞、峰林与野咖路线", "https://wanfenglin-guanwang.oss-cn-chengdu.aliyuncs.com/uploads/20240718/23ea4291a9570b94a1f8df9a012c18ec.jpg", 7, "山野户外全景", 2), ("private-family", "private-custom", "家庭专属定制", "贵州·按同行人和节奏安排", "https://news.cgtn.com/news/2023-06-23/Zhenyuan-ancient-town-a-must-see-in-Guizhou-1kRXUSXOP1m/img/6aead33b391640589740a7672c66a685/6aead33b391640589740a7672c66a685.jpeg", 1, "家庭专属定制", 0), ("private-business", "private-custom", "企业专属定制", "贵州·团建、会议与奖励旅行", "https://wanfenglin-guanwang.oss-cn-chengdu.aliyuncs.com/uploads/20240718/23ea4291a9570b94a1f8df9a012c18ec.jpg", 1, "企业专属定制", 1), ("private-wild", "private-custom", "山野深度定制", "贵州·溶洞、瀑降与小众目的地", "https://www.zurnal24.si/media/img/5e/d5/9526a56dba168aa136f3.jpeg", 1, "山野深度定制", 2), ) def _seed_wanfa() -> None: category_table = sa.table( "WanfaCategory", sa.column("id", sa.String()), sa.column("label", sa.String()), sa.column("sortOrder", sa.Integer()), sa.column("createdAt", sa.DateTime()), sa.column("updatedAt", sa.DateTime()), ) route_table = sa.table( "WanfaRoute", sa.column("id", sa.String()), sa.column("categoryId", sa.String()), sa.column("title", sa.String()), sa.column("subtitle", sa.Text()), sa.column("image", sa.String()), sa.column("routeCount", sa.Integer()), sa.column("demandKeyword", sa.String()), sa.column("sortOrder", sa.Integer()), sa.column("createdAt", sa.DateTime()), sa.column("updatedAt", sa.DateTime()), ) timestamp = datetime(2026, 1, 1) op.bulk_insert( category_table, [ {"id": item_id, "label": label, "sortOrder": sort_order, "createdAt": timestamp, "updatedAt": timestamp} for item_id, label, sort_order in SEED_CATEGORIES ], ) op.bulk_insert( route_table, [ { "id": item_id, "categoryId": category_id, "title": title, "subtitle": subtitle, "image": image, "routeCount": route_count, "demandKeyword": demand_keyword, "sortOrder": sort_order, "createdAt": timestamp, "updatedAt": timestamp, } for item_id, category_id, title, subtitle, image, route_count, demand_keyword, sort_order in SEED_ROUTES ], ) def upgrade() -> None: bind = op.get_bind() existing_tables = set(inspect(bind).get_table_names()) if "WanfaCategory" not in existing_tables: op.create_table( "WanfaCategory", sa.Column("id", sa.String(), nullable=False), sa.Column("label", sa.String(), nullable=False), sa.Column("sortOrder", sa.Integer(), nullable=False, server_default="0"), sa.Column("createdAt", sa.DateTime(), nullable=False), sa.Column("updatedAt", sa.DateTime(), nullable=False), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_WanfaCategory_sortOrder", "WanfaCategory", ["sortOrder"]) if "WanfaRoute" not in existing_tables: op.create_table( "WanfaRoute", sa.Column("id", sa.String(), nullable=False), sa.Column("categoryId", sa.String(), nullable=False), sa.Column("title", sa.String(), nullable=False), sa.Column("subtitle", sa.Text(), nullable=False), sa.Column("image", sa.String(), nullable=False), sa.Column("routeCount", sa.Integer(), nullable=False), sa.Column("demandKeyword", sa.String(), nullable=False), sa.Column("sortOrder", sa.Integer(), nullable=False, server_default="0"), sa.Column("createdAt", sa.DateTime(), nullable=False), sa.Column("updatedAt", sa.DateTime(), nullable=False), sa.ForeignKeyConstraint(["categoryId"], ["WanfaCategory.id"], ondelete="RESTRICT"), sa.PrimaryKeyConstraint("id"), ) op.create_index("ix_WanfaRoute_categoryId", "WanfaRoute", ["categoryId"]) op.create_index("ix_WanfaRoute_sortOrder", "WanfaRoute", ["sortOrder"]) if context.is_offline_mode(): _seed_wanfa() return category_table = sa.table("WanfaCategory", sa.column("id", sa.String())) route_table = sa.table("WanfaRoute", sa.column("id", sa.String())) category_exists = bind.execute(sa.select(category_table.c.id).limit(1)).first() is not None route_exists = bind.execute(sa.select(route_table.c.id).limit(1)).first() is not None if not category_exists and not route_exists: _seed_wanfa() def downgrade() -> None: bind = op.get_bind() existing_tables = set(inspect(bind).get_table_names()) if "WanfaRoute" in existing_tables: op.drop_table("WanfaRoute") if "WanfaCategory" in existing_tables: op.drop_table("WanfaCategory")