b0b816b0ee
- migrations/0001_init: 全部核心表(product/food_detail/product_msrp/product_source/brand/manufacturer/category/category_schema/unit/attribute_definition/product_image/merge_log) + 索引(gtin唯一/name trigram/JSONB GIN/category ltree/tsvector) + tsvector/updated_at 触发器 - 0002_seed_units: 单位字典(与 units.py 一致, 含中文别名) + 常用营养参数定义 - 0003_seed_categories: 食品品类骨架(GS1 GPC 映射 + 自建中文树, ltree) + 品类参数模板(营养基准 per_100g/ml) - CI 增加 migrations job: 用 postgres service 跑 migrate up + down 验证可逆 - 本地实跑 up/down/re-up 全部通过 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
54 lines
3.4 KiB
SQL
54 lines
3.4 KiB
SQL
-- Seed a FOOD-focused category skeleton.
|
|
-- Structure = GS1 GPC backbone (segment/family/class) mapped to a self-built
|
|
-- Chinese tree. ltree labels are english slugs (ltree forbids spaces/CJK);
|
|
-- Chinese names live in name_zh. gpc_brick_code on leaves is a representative
|
|
-- starter value to be replaced by a full official GPC import later.
|
|
|
|
-- Root segment: Food/Beverage/Tobacco (GPC segment 50000000)
|
|
INSERT INTO category (name_zh, name_en, parent_id, path, gpc_brick_code, level)
|
|
VALUES ('食品饮料', 'Food/Beverage', NULL, 'food', '50000000', 0);
|
|
|
|
-- Families (level 1)
|
|
INSERT INTO category (name_zh, name_en, parent_id, path, gpc_brick_code, level)
|
|
SELECT v.name_zh, v.name_en, c.id, v.path::ltree, v.code, 1
|
|
FROM (VALUES
|
|
('饮料', 'Beverages', 'food.beverages', '50130000'),
|
|
('乳制品蛋类','Dairy/Eggs', 'food.dairy', '50180000'),
|
|
('烘焙', 'Bakery', 'food.bakery', '50100000'),
|
|
('零食', 'Snacks', 'food.snacks', '50190000'),
|
|
('粮油', 'Staples/Oils', 'food.staple', '50160000'),
|
|
('调味品', 'Condiments', 'food.condiments', '50170000')
|
|
) AS v(name_zh, name_en, path, code)
|
|
JOIN category c ON c.path = 'food';
|
|
|
|
-- Classes / leaves (level 2) with representative GPC brick codes
|
|
INSERT INTO category (name_zh, name_en, parent_id, path, gpc_brick_code, level)
|
|
SELECT v.name_zh, v.name_en, c.id, v.path::ltree, v.code, 2
|
|
FROM (VALUES
|
|
('包装饮用水', 'Bottled water', 'food.beverages.water', '10000224', 'food.beverages'),
|
|
('碳酸饮料', 'Carbonated', 'food.beverages.carbonated', '10000225', 'food.beverages'),
|
|
('果汁', 'Juice', 'food.beverages.juice', '10000226', 'food.beverages'),
|
|
('牛奶', 'Milk', 'food.dairy.milk', '10000158', 'food.dairy'),
|
|
('酸奶', 'Yogurt', 'food.dairy.yogurt', '10000159', 'food.dairy'),
|
|
('奶酪', 'Cheese', 'food.dairy.cheese', '10000160', 'food.dairy'),
|
|
('面包', 'Bread', 'food.bakery.bread', '10000040', 'food.bakery'),
|
|
('饼干', 'Biscuits', 'food.bakery.biscuits', '10000041', 'food.bakery'),
|
|
('薯片膨化', 'Chips/Snacks', 'food.snacks.chips', '10000310', 'food.snacks'),
|
|
('巧克力', 'Chocolate', 'food.snacks.chocolate', '10000311', 'food.snacks'),
|
|
('大米', 'Rice', 'food.staple.rice', '10000500', 'food.staple'),
|
|
('面条', 'Noodles', 'food.staple.noodles', '10000501', 'food.staple'),
|
|
('食用油', 'Cooking oil', 'food.staple.cooking_oil', '10000502', 'food.staple'),
|
|
('酱油', 'Soy sauce', 'food.condiments.soy_sauce', '10000600', 'food.condiments'),
|
|
('食盐', 'Table salt', 'food.condiments.salt', '10000601', 'food.condiments')
|
|
) AS v(name_zh, name_en, path, code, parent_path)
|
|
JOIN category c ON c.path = v.parent_path::ltree;
|
|
|
|
-- Parameter templates: leaf food categories use per_100g/ml nutrition basis.
|
|
INSERT INTO category_schema (category_id, required_attributes, recommended_attributes, nutriment_basis)
|
|
SELECT id,
|
|
ARRAY['net_content'],
|
|
ARRAY['energy','proteins','fat','carbohydrates','sugars','salt'],
|
|
CASE WHEN path <@ 'food.beverages' THEN 'per_100ml' ELSE 'per_100g' END
|
|
FROM category
|
|
WHERE level = 2;
|