# BD_Manual：tenant_id INTEGER → BIGINT 迁移

> 日期：2026-03-03
> 涉及库：`etl_feiqiu` / `test_etl_feiqiu`、`zqyy_app` / `test_zqyy_app`
> 迁移脚本：
>   - `db/etl_feiqiu/migrations/2026-03-03__alter_tenant_id_int_to_bigint.sql`
>   - `db/zqyy_app/migrations/2026-03-03__alter_tenant_id_int_to_bigint.sql`
> 直接原因：飞球 tenant_id（如 2790683160709957）远超 int4 上限（2,147,483,647），导致写入溢出
> Prompt 摘要：修复 tenant_id int4 溢出问题，迁移为 bigint

---

## 1. 变更说明

### 变更前

| 库 | Schema | 表 | 列 | 类型 |
|----|--------|----|----|------|
| etl_feiqiu | dws | dws_assistant_order_contribution | tenant_id | INTEGER (int4) NOT NULL |
| zqyy_app | auth | site_code_mapping | tenant_id | INTEGER (int4) NULL |

### 变更后

| 库 | Schema | 表 | 列 | 类型 |
|----|--------|----|----|------|
| etl_feiqiu | dws | dws_assistant_order_contribution | tenant_id | BIGINT (int8) NOT NULL |
| zqyy_app | auth | site_code_mapping | tenant_id | BIGINT (int8) NULL |

### 级联影响

| 对象 | 类型 | 处理方式 |
|------|------|---------|
| `app.v_dws_assistant_order_contribution` (ETL 库) | RLS 视图 | DROP → ALTER → 重建（SELECT *） |
| `fdw_etl.v_dws_assistant_order_contribution` (App 库) | FDW 外部表 | DROP → IMPORT FOREIGN SCHEMA 重新导入 |
| `app.v_dws_assistant_order_contribution` (App 库) | RLS 视图 | 自动继承 FDW 外部表类型 |

---

## 2. 兼容性影响

| 组件 | 影响 | 说明 |
|------|------|------|
| ETL 任务 | 无影响 | `assistant_order_contribution_task.py` 从 DWD 层读取 tenant_id（已是 bigint），写入 DWS 现在类型匹配 |
| 后端 API | 无影响 | 通过 FDW 视图读取，类型自动跟随源表 |
| 小程序 | 无影响 | 不直接使用 tenant_id |
| `init_test_user.py` | 已更新 | 移除 `_safe_tenant_id()` 中的 int4 范围检查降级逻辑 |

---

## 3. 回滚策略

### ETL 库回滚
```sql
BEGIN;
DROP VIEW IF EXISTS app.v_dws_assistant_order_contribution CASCADE;
ALTER TABLE dws.dws_assistant_order_contribution ALTER COLUMN tenant_id TYPE integer;
CREATE OR REPLACE VIEW app.v_dws_assistant_order_contribution AS
SELECT * FROM dws.dws_assistant_order_contribution
WHERE site_id = current_setting('app.current_site_id')::bigint;
GRANT SELECT ON app.v_dws_assistant_order_contribution TO app_reader;
COMMIT;
```

### App 库回滚
```sql
BEGIN;
ALTER TABLE auth.site_code_mapping ALTER COLUMN tenant_id TYPE integer;
COMMIT;
```

### 代码回滚
恢复 `scripts/ops/init_test_user.py` 中 `_safe_tenant_id()` 的 int4 范围检查逻辑。

---

## 4. 验证 SQL

### ETL 库（test_etl_feiqiu）

```sql
-- 1. 确认 dws 表 tenant_id 类型
SELECT column_name, data_type, udt_name
  FROM information_schema.columns
 WHERE table_schema = 'dws'
   AND table_name = 'dws_assistant_order_contribution'
   AND column_name = 'tenant_id';
-- 预期：data_type = 'bigint', udt_name = 'int8'

-- 2. 确认 RLS 视图存在且类型正确
SELECT column_name, data_type
  FROM information_schema.columns
 WHERE table_schema = 'app'
   AND table_name = 'v_dws_assistant_order_contribution'
   AND column_name = 'tenant_id';
-- 预期：data_type = 'bigint'

-- 3. 确认全库无残留 int4 tenant_id
SELECT table_schema, table_name
  FROM information_schema.columns
 WHERE column_name = 'tenant_id' AND udt_name = 'int4';
-- 预期：0 行
```

### App 库（test_zqyy_app）

```sql
-- 1. 确认 auth 表 tenant_id 类型
SELECT column_name, data_type, udt_name
  FROM information_schema.columns
 WHERE table_schema = 'auth'
   AND table_name = 'site_code_mapping'
   AND column_name = 'tenant_id';
-- 预期：data_type = 'bigint', udt_name = 'int8'

-- 2. 确认 FDW 外部表类型正确
SELECT column_name, data_type
  FROM information_schema.columns
 WHERE table_schema = 'fdw_etl'
   AND table_name = 'v_dws_assistant_order_contribution'
   AND column_name = 'tenant_id';
-- 预期：data_type = 'bigint'

-- 3. 确认全库无残留 int4 tenant_id
SELECT table_schema, table_name
  FROM information_schema.columns
 WHERE column_name = 'tenant_id' AND udt_name = 'int4';
-- 预期：0 行
```
