muyu-apiserver/deploy/mysql/migrations/20260403_data_migration.sql

66 lines
2.8 KiB
MySQL
Raw Normal View History

-- Data migration: split existing inv_product flat data into pan + bolt records.
-- Run AFTER 20260403_add_pan_and_bolt.sql but BEFORE 20260403_drop_legacy_columns.sql.
-- Wrapped in a stored procedure so re-runs on an already-migrated database
-- (where `location` was already dropped) silently succeed rather than error.
-- MySQL validates column names at call time, not at CREATE PROCEDURE time,
-- so the IF guard prevents the INSERTs from running when the column is absent.
DROP PROCEDURE IF EXISTS _migrate_inv_pan_bolt;
DELIMITER $$
CREATE PROCEDURE _migrate_inv_pan_bolt()
BEGIN
DECLARE v_has_location TINYINT DEFAULT 0;
SELECT COUNT(*) INTO v_has_location
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = DATABASE()
AND TABLE_NAME = 'inv_product'
AND COLUMN_NAME = 'location';
IF v_has_location = 1 THEN
-- Step 1: one default pan per product, position taken from legacy `location`
INSERT INTO inv_product_pan (pan_id, product_id, name, position, sort_order, tenant_id)
SELECT
CONCAT('pan_mig_', product_id),
product_id,
'A',
COALESCE(location, ''),
1,
COALESCE(tenant_id, '')
FROM inv_product
WHERE deleted_at IS NULL
AND product_id NOT IN (SELECT DISTINCT product_id FROM inv_product_pan);
-- Step 2: bolt records, one per unit_piece (or one if unit_pieces = 0)
INSERT INTO inv_product_bolt (bolt_id, pan_id, length_m, sort_order, tenant_id)
SELECT
CONCAT('bolt_mig_', product_id, '_', seq.n),
CONCAT('pan_mig_', product_id),
CASE
WHEN unit_pieces > 0 THEN ROUND(stock_quantity / unit_pieces, 2)
ELSE stock_quantity
END,
seq.n,
COALESCE(tenant_id, '')
FROM inv_product
CROSS JOIN (
SELECT 1 AS n UNION ALL SELECT 2 UNION ALL SELECT 3 UNION ALL SELECT 4 UNION ALL SELECT 5
UNION ALL SELECT 6 UNION ALL SELECT 7 UNION ALL SELECT 8 UNION ALL SELECT 9 UNION ALL SELECT 10
UNION ALL SELECT 11 UNION ALL SELECT 12 UNION ALL SELECT 13 UNION ALL SELECT 14 UNION ALL SELECT 15
UNION ALL SELECT 16 UNION ALL SELECT 17 UNION ALL SELECT 18 UNION ALL SELECT 19 UNION ALL SELECT 20
) seq
WHERE deleted_at IS NULL
AND stock_quantity > 0
AND seq.n <= GREATEST(unit_pieces, 1)
AND CONCAT('pan_mig_', product_id) IN (SELECT pan_id FROM inv_product_pan);
END IF;
END$$
DELIMITER ;
CALL _migrate_inv_pan_bolt();
DROP PROCEDURE IF EXISTS _migrate_inv_pan_bolt;
-- Verification queries (run manually to check)
-- SELECT COUNT(*) AS pan_count FROM inv_product_pan WHERE pan_id LIKE 'pan_mig_%';
-- SELECT COUNT(*) AS bolt_count FROM inv_product_bolt WHERE bolt_id LIKE 'bolt_mig_%';