# 在线表单与第三方数据库 ## 架构 - **平台库**(`db_config=default`):`FormMeta`、权限、字典、`core_user` / 省市区等元数据表。 - **业务库**(`FormMeta.db_config` 为连接 code):表单主表/子表 CRUD、导入导出。 业务逻辑统一由 `FormDataService` + `DynamicSQLBuilder` 处理;仅在 `create_form_data_adapter()` 分叉: - `default` → `PlatformSessionAdapter`(SQLAlchemy `AsyncSession`) - 其他 code → `ExternalConnectionAdapter`(`DatabaseManager` Handler + 字面量参数 SQL) ## 与 default 对齐的近期改动 | 项 | 说明 | |----|------| | PostgreSQL 多库 | 外部 PG 执行/事务时按 `main_table_database` 或子表 `table_database` 切换连接库(`_table_exec_database`) | | 子表跨库 | 子表 CRUD/查询传入子表 `table_database`,不再一律使用主表库名 | | 表单选择器筛选 | 列表按显示名筛选时,`relation_type=form_data` 会查关联表单业务表并转为 ID | | 导入提交粒度 | **default**:单事务内分批 `db.commit()`;**第三方**:每批数据独立 Handler 事务,成功批次已提交、失败批次不影响已成功批次 | | 库名校验 | `validate_form_tables` 返回 `database_warnings`(MySQL 跨库、PG 未配默认库等) | ## 回归检查清单 | 用例 | 说明 | |------|------| | CRUD 主+子 | 外部库新增/编辑/删除含子表 | | PG 多 database | 连接无 default_database 时依赖表单 `main_table_database` | | 用户/部门/省市区 | 列表展示与筛选(始终查平台库 `core_*`) | | 关联他表 | 同连接与跨连接 formData;按名称列表筛选 | | 导入 | 覆盖 / 仅新增 / upsert;第三方分批提交 | | 发布 | `validate_form_tables`(含 `database_warnings`) | ## 限制 - 系统连接(`is_system`)不可写入表单业务表。 - 跨方言导入自动建表会拒绝(需同引擎或手工建表);导入预检查返回 `target_db_type`,前端与导出 JSON 中的 `export_db_type` 比对并提示。 - 游标分页:SQL Server / Oracle 使用等值前缀 + OR 链;PostgreSQL / MySQL 使用行值比较。 - **SQL Server 中文**:字符串列须为 `NVARCHAR` / `NCHAR` / `NVARCHAR(MAX)`,勿用 `VARCHAR`/`CHAR`/`TEXT`,否则中文会变成 `?`。新建表已默认映射为 N* 类型;已有表需 `ALTER COLUMN` 迁移。 - **Oracle**:连接使用 service name(`default_database` / 连接配置),不按 PostgreSQL 方式切换 database;schema 一般为当前用户。 - **MySQL**:表名通过 `` `database`.`table` `` 限定;连接默认库与 `main_table_database` 不一致时需账号具备跨库权限。 - **平台关联表**:用户/部门/字典/省市区等仅查平台库;业务表请勿配置为 `core_user` 等平台表名。 - **单请求多 PG database**:主表与子表若在不同 PostgreSQL database,无法在同一 Handler 事务中原子提交,应保证主/子表在同一库或接受非原子语义。