# CSV/Excel 导入模板 本目录定义真实数据进入系统前的标准格式。模板当前以 CSV 提供,Excel 可按相同列名保存为首行表头后再导出为 CSV。 ## 使用原则 - 表头必须与模板完全一致。 - 文件编码建议使用 UTF-8 或 UTF-8 with BOM。 - 所有金额和面积字段只填写数字,不带单位、逗号或中文说明。 - `source` 必须填写可识别的数据来源名称,不允许写数据库连接串、密码、本地敏感路径。 - 单次导入必须先创建或关联一条 `audit.ingestion_runs` 记录。 - 校验通过不代表数据一定正确,只代表结构、类型和值域满足入库前置条件。 ## 模板清单 | 模板 | 目标表 | 主键 | 用途 | | --- | --- | --- | --- | | `area_monthly_metrics.csv` | `silver.area_monthly_metrics` | `area_id`, `month` | 板块月度成交、挂牌、租金、供应、信贷和政策信号 | | `neighborhood_monthly_metrics.csv` | `silver.neighborhood_monthly_metrics` | `neighborhood_id`, `month` | 小区月度成交、挂牌、租金和可售样本 | | `policy_events.csv` | `raw.policy_events` | `event_date`, `title` | 政策事件留痕和人工影响评分 | | `land_sales.csv` | `raw.land_sales` | `parcel_id` | 土地成交记录,用于供给压力研究 | ## 字段规则 字段规格的机器可读版本位于 `config/import_templates.json`。Python CLI 和 Rust API 均应以该文件为准。 ### 通用类型 | 类型 | 规则 | | --- | --- | | `text` | 非空文本,若字段非必填则可为空 | | `integer` | 整数,可配置最小值和最大值 | | `decimal` | 数字,可配置最小值和最大值 | | `month` | `YYYY-MM`,月份必须是 01-12 | | `date` | `YYYY-MM-DD`,日期必须真实存在 | | `url` | 空值或 `http://` / `https://` URL | | `enum` | 必须属于规格中的 `allowed_values` | ## CLI 校验 ```bash PYTHONPATH=src python3 -m shanghai_housing validate-import \ --template area_monthly_metrics \ --file docs/import_templates/area_monthly_metrics.csv ``` 通过时输出行数和模板名;失败时逐行返回错误信息。 ## 原始文件指纹 导入前先计算文件指纹,用于登记 `audit.raw_artifacts` 并识别重复文件。 ```bash PYTHONPATH=src python3 -m shanghai_housing fingerprint-file \ --file docs/import_templates/area_monthly_metrics.csv ``` 输出内容包含 `original_filename`、`raw_uri`、`sha256`、`size_bytes` 和 `mime_type`,可作为 `POST /api/v1/raw-artifacts` 的主要 payload。 ## API 校验 ```bash curl -X POST http://127.0.0.1:8080/api/v1/imports/validate \ -H 'content-type: application/json' \ -d '{ "template_name": "area_monthly_metrics", "rows": [ { "area_id": "qiantan", "month": "2026-05", "transaction_count": "93", "transaction_price_psm": "122500", "listing_count": "380", "listing_price_psm": "126500", "median_days_on_market": "53", "rent_price_psm": "192", "new_supply_units": "60", "land_residential_gfa_sqm": "0", "mortgage_rate_pct": "3.35", "policy_signal": "1", "source": "manual_research" } ] }' ``` ## API 原始文件登记 ```bash curl -X POST http://127.0.0.1:8080/api/v1/raw-artifacts \ -H 'content-type: application/json' \ -d '{ "run_id": 1, "source_id": 1, "original_filename": "area_monthly_metrics.csv", "raw_uri": "raw://sha256//area_monthly_metrics.csv", "sha256": "<64-character-lowercase-sha256>", "size_bytes": 2048, "mime_type": "text/csv", "uploaded_by": "researcher" }' ``` 同一个 `sha256` 重复登记时,API 返回已有 artifact,并可将新的导入批次关联到该 artifact。 ## API 执行导入 执行顺序: 1. 创建或选择数据源。 2. 创建 `audit.ingestion_runs` 批次。 3. 使用文件指纹登记 `audit.raw_artifacts`。 4. 调用执行接口写入 `raw.import_rows` 和对应 `silver` 表。 ```bash curl -X POST http://127.0.0.1:8080/api/v1/imports/execute \ -H 'content-type: application/json' \ -d '{ "template_name": "area_monthly_metrics", "run_id": 1, "raw_artifact_id": 1, "rows": [ { "area_id": "qiantan", "month": "2026-05", "transaction_count": "93", "transaction_price_psm": "122500", "listing_count": "380", "listing_price_psm": "126500", "median_days_on_market": "53", "rent_price_psm": "192", "new_supply_units": "60", "land_residential_gfa_sqm": "0", "mortgage_rate_pct": "3.35", "policy_signal": "1", "source": "manual_research" } ] }' ``` 当前执行接口支持 `area_monthly_metrics` 和 `neighborhood_monthly_metrics`。校验失败时不会写入业务表,并会把导入批次标记为 `failed`。