diff --git a/db_migrations/phase10_purchase_supplier_link_text.sql b/db_migrations/phase10_purchase_supplier_link_text.sql new file mode 100644 index 0000000..7b0855f --- /dev/null +++ b/db_migrations/phase10_purchase_supplier_link_text.sql @@ -0,0 +1,68 @@ +-- ============================================================================= +-- 采购申请「商家地址链接」放宽为 text +-- +-- 现象 +-- 新建采购申请时粘贴电商商品链接报错。实测该链接 **516 字符**,而 +-- purchase_request.supplier_link 是 varchar(500) —— 超出 16 个字符, +-- PostgreSQL 直接拒绝(value too long for type character varying(500))。 +-- +-- 为什么用 text 而不是把 500 调大 +-- 电商外链(淘宝/1688 等)普遍带很长的跟踪参数,长度没有稳定上界: +-- 本例已 516,再叠加一轮营销参数就可能破千。任何有限的 varchar(N) 都只是 +-- 把报错往后推,而且**截断是静默的** —— 用户只会觉得「链接打不开」。 +-- 同 material_base.purchase_link 的处理(那边一开始就用 text)。 +-- +-- 附带确认(无需改动) +-- 全库扫描 varchar 且列名像 link/url/photo/image/signature/path 的列,仅本列 +-- 是用户粘贴的外链;sys_menu.path(200)、sys_warehouse_location.full_path(500) +-- 是内部生成数据,stock_adjustment.linked_*(50/100) 是 SKU 与单号,均不受影响。 +-- +-- 幂等:ALTER TYPE 对已是 text 的列会报错,故用 DO 块先判断当前类型。 +-- 不含 psql 元命令,DataGrip 可直接执行。 +-- ============================================================================= + +BEGIN; + +DO $$ +BEGIN + IF EXISTS ( + SELECT 1 FROM information_schema.columns + WHERE table_name = 'purchase_request' + AND column_name = 'supplier_link' + AND data_type = 'character varying' + ) THEN + -- 加长类型不会丢数据(varchar → text 是放宽,不是转换) + ALTER TABLE purchase_request + ALTER COLUMN supplier_link TYPE text; + END IF; +END $$; + +COMMENT ON COLUMN purchase_request.supplier_link IS + '商家地址链接。text 无长度上限 —— 电商外链常带很长的跟踪参数,varchar(N) 会把「链接太长」变成静默失败'; + +COMMIT; + + +-- ============================================================================= +-- 执行后核对 +-- ============================================================================= +SELECT '=== 1) 列类型应为 text(character_maximum_length 为空)===' AS "核对项"; +SELECT column_name, data_type, character_maximum_length AS 上限 + FROM information_schema.columns + WHERE table_name = 'purchase_request' AND column_name = 'supplier_link'; + +SELECT '=== 2) 现有数据长度分布(确认无截断)===' AS "核对项"; +SELECT count(*) AS 链接总数, + count(*) FILTER (WHERE supplier_link IS NOT NULL AND supplier_link <> '') AS 非空数, + coalesce(max(length(supplier_link)), 0) AS 最长字符数 + FROM purchase_request; + + +-- ============================================================================= +-- 回滚段 +-- 注意:回滚前必须先确认没有超过 500 字符的数据,否则会失败。 +-- ============================================================================= +-- BEGIN; +-- ALTER TABLE purchase_request +-- ALTER COLUMN supplier_link TYPE varchar(500); +-- COMMIT; diff --git a/inventory-backend/app/models/purchase.py b/inventory-backend/app/models/purchase.py index a1ff2b4..da1b30a 100644 --- a/inventory-backend/app/models/purchase.py +++ b/inventory-backend/app/models/purchase.py @@ -17,7 +17,12 @@ class PurchaseRequest(db.Model): spec_model = db.Column(db.String(255), comment='规格型号') quantity = db.Column(db.Numeric(19, 4), nullable=False, comment='采购数量') purchase_date = db.Column(db.Date, nullable=False, comment='采购时间') - supplier_link = db.Column(db.String(500), comment='商家地址链接') + # ★ 用 Text 而非 String(N):电商外链常带很长的跟踪参数,长度没有稳定上界 + # (实测一条淘宝链接已 516 字符,超过原先的 varchar(500) 直接报错)。 + # 任何有限的 varchar(N) 都只是把报错往后推,且**截断是静默的** —— + # 用户只会觉得「链接打不开」。同 material_base.purchase_link 的处理。 + # DDL 见 db_migrations/phase10_purchase_supplier_link_text.sql + supplier_link = db.Column(db.Text, comment='商家地址链接') remark = db.Column(db.Text, comment='备注信息') images = db.Column(db.Text, comment='图片列表JSON') unit_price = db.Column(db.Numeric(19, 4), default=0, comment='不含税单价')