|
|
## 一对多关系的子表入库
|
|
|
|
|
|
注意,本节所描述的功能。只在不开启兼容选项(compatible)时才能使用。
|
|
|
|
|
|
该功能用于处理一对多关系的数据。 这种数据通常被设计为存储在两个关联的表中。
|
|
|
主表用于存储基本信息,关联表用于存储详情。主表与关联表为一对多关系。
|
|
|
该功能可以实现将一条涉及主表及关联表的数据,一次性完成所有相关表的入库操作。
|
|
|
|
|
|
如下图的所展示的表结构用于存储团队(team)及其成员(member)。
|
|
|
|
|
|

|
|
|
|
|
|
```puml
|
|
|
@startuml
|
|
|
|
|
|
' hide the spot
|
|
|
hide circle
|
|
|
|
|
|
entity "tb_team" {
|
|
|
*id : number <<generated>>
|
|
|
--
|
|
|
*name : text
|
|
|
}
|
|
|
|
|
|
entity "tb_members" {
|
|
|
*id : number <<generated>>
|
|
|
--
|
|
|
*team_id : number <<FK>>
|
|
|
*name : text
|
|
|
}
|
|
|
|
|
|
tb_team --|{ tb_members
|
|
|
|
|
|
@enduml
|
|
|
```
|
|
|
|
|
|
通过本模块对如下记录进行入表操作。
|
|
|
|
|
|
tb_team
|
|
|
|
|
|
|id|name|
|
|
|
|----|----|
|
|
|
|1|marvel|
|
|
|
|
|
|
tb_members
|
|
|
|
|
|
|id|team_id|member_name|
|
|
|
|----|----|----|
|
|
|
|1|1|Iron Man|
|
|
|
|2|1|Spider Man|
|
|
|
|
|
|
|
|
|
需要按如下结构组装数据包作为输入传给本模块:
|
|
|
|
|
|
```json
|
|
|
{
|
|
|
"id": 1,
|
|
|
"name": "marvel",
|
|
|
"members": [
|
|
|
{
|
|
|
"id": 1,
|
|
|
"member_name": "Iron Man"
|
|
|
},
|
|
|
{
|
|
|
"id": 2,
|
|
|
"member_name": "Spider Man"
|
|
|
}
|
|
|
],
|
|
|
|
|
|
"sync_condition": {
|
|
|
"data_type": "teams",
|
|
|
"operation":"upsert"
|
|
|
}
|
|
|
}
|
|
|
```
|
|
|
|
|
|
### 数据展开(table_explode)
|
|
|
table_explode是data_type的子配置项,用于指明将输入数据的特定字段内容展开到相应的数据表中。
|
|
|
```yaml
|
|
|
table_explode: #(3)
|
|
|
- table: "tb_members" #(4)
|
|
|
explode_field: "members" #(5)
|
|
|
attach_fields: #(6)
|
|
|
- field: "team_id"
|
|
|
refer: "id"
|
|
|
overwrite: #(7)
|
|
|
foreign_keys: #(8)
|
|
|
- field: "team_id"
|
|
|
refer: "id"
|
|
|
logical_delete: True #(9)
|
|
|
deleted_field: "deleted"
|
|
|
deleted_field_value: 1
|
|
|
deleted_field_default: 0
|
|
|
```
|
|
|
|
|
|
|配置项|子配置项|是否必填|数据类型|说明|
|
|
|
|----|----|----|----|----|
|
|
|
|explode_field| |必填|字符串|指定需要展开的数据字段。该字段必需为数据类型,且数组的元素为字典。|
|
|
|
|table| |必填|字符串|展开的数据需要入的数据库表。|
|
|
|
|attach_fields| |选填|数组|定义展开的数据中,需要附加输入数据中的哪些字段。|
|
|
|
|overwrite| |选填|字典|覆盖更新参数|
|
|
|
| |foreign_keys|必填|数组|指明用于筛选子表中相关数据的字段|
|
|
|
| |logical_delete|选填|布尔型|是否是逻辑删除|
|
|
|
| |deleted_field|选填|字符串|逻辑删除标志字段的字段名|
|
|
|
| |deleted_field_value|选填|字符串|表示逻辑删除含义的字段值|
|
|
|
| |deleted_field_default|选填|字符串|逻辑删除字段的默认值。如果数据中没有指定该字段的值,则会设为该值|
|
|
|
|
|
|
|
|
|
#### 子表更新的几种模式
|
|
|
1. 增量更新
|
|
|
|
|
|
2. 覆盖更新
|
|
|
|
|
|
|
|
|
#### 子表需要附加主表的一些数据(attach_fields)
|
|
|
|
|
|
|
|
|
#### 覆盖更新(overwrite)
|
|
|
在数据维护中会有一种场景:需要把子表中相关记录整体替换为输入数据中的内容。如前面的例子中:
|
|
|
|
|
|
marvel团队原来的团队成员为:
|
|
|
* Iron Man
|
|
|
* Spider Man
|
|
|
|
|
|
输入数据如下:
|
|
|
```json
|
|
|
{
|
|
|
"id": 1,
|
|
|
"name": "marvel",
|
|
|
"members": [
|
|
|
{
|
|
|
"id": 2,
|
|
|
"member_name": "Spider Man"
|
|
|
},
|
|
|
{
|
|
|
"id": 3,
|
|
|
"member_name": "Bat Man"
|
|
|
}
|
|
|
]
|
|
|
}
|
|
|
```
|
|
|
|
|
|
希望更新后Iron Man被删除. 团队成员变为:
|
|
|
* Spider Man
|
|
|
* Bat Man
|
|
|
|
|
|
实现覆盖更新需要在配置使用overwrite选项来完成。
|
|
|
|
|
|
|配置项目|说明|
|
|
|
|----|----|
|
|
|
|foreign_keys|指明用于筛选子表中相关数据的字段|
|
|
|
|logical_delete|是否是逻辑删除|
|
|
|
|deleted_field|逻辑删除标志字段的字段名|
|
|
|
|deleted_field_value| 表示逻辑删除含义的字段值|
|
|
|
|deleted_field_default| 逻辑删除字段的默认值。如果数据中没有指定该字段的值,则会设为该值|
|
|
|
|
|
|
```yaml
|
|
|
table_explode: #(3)
|
|
|
- table: "tb_members" #(4)
|
|
|
explode_field: "members" #(5)
|
|
|
attach_fields: #(6)
|
|
|
- field: "team_id"
|
|
|
refer: "id"
|
|
|
overwrite: #(7)
|
|
|
foreign_keys: #(8)
|
|
|
- field: "team_id"
|
|
|
refer: "id"
|
|
|
logical_delete: True #(9)
|
|
|
deleted_field: "deleted"
|
|
|
deleted_field_value: 1
|
|
|
deleted_field_default: 0
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
### 配置文件示例
|
|
|
|
|
|
配置文件中,名为teams的data_type定义如下:
|
|
|
|
|
|
```yaml
|
|
|
catalogues:
|
|
|
- data_type: #(1)
|
|
|
- name: "teams" #(2)
|
|
|
tables: ['tb_team', "tb_members"]
|
|
|
|
|
|
table_explode: #(3)
|
|
|
- table: "tb_members" #(4)
|
|
|
explode_field: "members" #(5)
|
|
|
attach_fields: #(6)
|
|
|
- field: "team_id"
|
|
|
refer: "id"
|
|
|
overwrite: #(7)
|
|
|
foreign_keys: #(8)
|
|
|
- field: "team_id"
|
|
|
refer: "id"
|
|
|
logical_delete: True #(9)
|
|
|
deleted_field: "deleted"
|
|
|
deleted_field_value: 1
|
|
|
deleted_field_default: 0
|
|
|
|
|
|
|
|
|
|
|
|
#(1) data_type为列表类型,在一个catalog下可以定义多个data_type
|
|
|
#(2) 名为teams的data_type涉及两个表:tb_team及tb_members,
|
|
|
#(3) 定义哪些表的数据是从输入数据的特定字段展开得到的。 table_explode是列表类型。
|
|
|
#(4) 表tb_members需要根据输入数据中的字段 members,进行展开
|
|
|
#(6) 在展开的数据中,要加上字段team_id,该字段的值为输入数据中字段id的值
|
|
|
#(7) 使用覆盖方式更新
|
|
|
#(8) 以team_id字段tb_members选择要覆盖的数据,该字段的值为输入数据中字段id的值
|
|
|
#(9) 执行逻辑删除。删除标志字段为 deleted, 其值为1表示删除
|
|
|
```
|
|
|
|