@dazitech/cli 3.0.5 → 3.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/dist/clis/dazi-app.js +16 -13
- package/dist/clis/dazi-flow.js +48 -28
- package/dist/clis/dazi-onto.js +7 -6
- package/dist/clis/dazi.js +9 -8
- package/dist/docs/flow/ai-workflow-playbook.md +4 -2
- package/dist/docs/flow/flow-project-guide.md +9 -5
- package/dist/docs/flow/flows-guide.md +2 -2
- package/dist/docs/flow/node-code-guide.md +408 -401
- package/dist/docs/flow/run-guide.md +13 -6
- package/dist/docs/flow/variables-guide.md +407 -406
- package/dist/docs/guides/troubleshooting.md +1 -1
- package/dist/docs/index.json +1 -1
- package/dist/examples/index.json +1 -1
- package/dist/prompts/flow/ai-workflow-playbook.md +4 -2
- package/dist/prompts/flow/flow-design.md +12 -9
- package/dist/prompts/flow/run-fix-loop.md +37 -22
- package/dist/prompts/index.json +1 -1
- package/package.json +1 -1
|
@@ -1,406 +1,407 @@
|
|
|
1
|
-
# 流程变量系统指南
|
|
2
|
-
|
|
3
|
-
**文档 ID**: `flow/variables-guide`
|
|
4
|
-
**适用**: `dazi-vscode` 流程项目、`python-script` / `sql-query` 等代码节点
|
|
5
|
-
**概念来源**: 搭子数据流程引擎统一变量模型(对齐 devend《011》),详见 `dazi/docs/279-dazi-dataflow数据流程功能总结.md` §3
|
|
6
|
-
|
|
7
|
-
**相关文档**
|
|
8
|
-
|
|
9
|
-
- [数据流程项目开发指南](./flow-project-guide.md) — 目录、`debug_run_id`、开发循环
|
|
10
|
-
- [节点代码编写指南](./node-code-guide.md) — 各节点 `code.*` 约定
|
|
11
|
-
- [Flow 运行与测试](./run-guide.md) — `node-exec`、`variable pull/sync`
|
|
12
|
-
|
|
13
|
-
---
|
|
14
|
-
|
|
15
|
-
## 1. 什么是流程变量
|
|
16
|
-
|
|
17
|
-
流程引擎把 **参数、中间表、最终结果** 统一抽象为 **变量(Variable)**,在一次 Run 内按 **变量名** 读写,而不必处处依赖画布连线传递文件路径。
|
|
18
|
-
|
|
19
|
-
| 概念 | 说明 |
|
|
20
|
-
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
21
|
-
| **变量名** | 字符串标识,如 `sales_raw`、`V1`、`销售表`;由节点配置 **`output_variable_name`** 或脚本 **`set_table_output` / `set_scalar_output`** 登记 |
|
|
22
|
-
| **变量作用域** | 绑定到某次 **`flow_runs`**;日常调试对应 **`ads_flows.debug_run_id`** |
|
|
23
|
-
| **登记时机** | 节点执行成功后,引擎读取 **`output_variable_name`**,将输出写入当前 Run 的 **`flow_run_variables`** |
|
|
24
|
-
|
|
25
|
-
**本地开发时**:变量不在 `flow.json` 里,而在调试 Run 中;CLI/扩展通过 API 拉取 schema + 预览到 **`变量/<名>.json`**。
|
|
26
|
-
|
|
27
|
-
---
|
|
28
|
-
|
|
29
|
-
## 2. 存储类型
|
|
30
|
-
|
|
31
|
-
| 类型 | 典型场景 | 存储 | `get_variable` 行为 |
|
|
32
|
-
| ------------------- | ------------------------------------ | --------------------------------- | ---------------------------------------- |
|
|
33
|
-
| **table(表变量)** | SQL 结果、Python `result_df`、文件源 | Parquet 落盘,库中 `value` 为路径 | 自动 `pd.read_parquet` → **`DataFrame`** |
|
|
34
|
-
| **text(标量)** | 计数、标志位、质检综合分 | 库中 `value` 为字符串 | 返回 Python 原生值(str/int/float 等) |
|
|
35
|
-
|
|
36
|
-
表变量是流程开发中最常用的类型;标量多用于质检分数、状态位等。
|
|
37
|
-
|
|
38
|
-
---
|
|
39
|
-
|
|
40
|
-
## 3. 产生变量:`output_variable_name`
|
|
41
|
-
|
|
42
|
-
在 **设计器属性面板** 或 `flow.json` → 节点 `data` 中配置:
|
|
43
|
-
|
|
44
|
-
```json
|
|
45
|
-
{
|
|
46
|
-
"type": "custom",
|
|
47
|
-
"data": {
|
|
48
|
-
"type": "sql-query",
|
|
49
|
-
"output_variable_name": "sales_clean",
|
|
50
|
-
"connectionId": "..."
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
```
|
|
54
|
-
|
|
55
|
-
**规则**
|
|
56
|
-
|
|
57
|
-
1. 节点成功执行后,引擎以 **`output_variable_name`** 为键登记变量(表 → Parquet 路径)。
|
|
58
|
-
2. 下游节点通过 **同名** 引用该变量(SQL 表名 / Python `get_variable('sales_clean')`)。
|
|
59
|
-
3. 变量名须 **全流程内唯一**;建议英文+下划线,中文名也支持(SQL 会自动加双引号)。
|
|
60
|
-
4. 未配置 `output_variable_name` 的节点,输出不会进入变量表(仍可能有入边 Parquet,但不便于单节点调试)。
|
|
61
|
-
|
|
62
|
-
**Python 多表输出**
|
|
63
|
-
|
|
64
|
-
- 主表:赋值 **`result_df`**(与 `output_variable_name` 对应)。
|
|
65
|
-
- 附加表:**`set_table_output('other_table', df)`**(`excel-python` 主输出也须 `set_table_output` 与 `output_variable_name` 同名)。
|
|
66
|
-
|
|
67
|
-
**标量输出**:**`set_scalar_output('score', 95.5)`**,变量名由画布质检配置或业务约定。
|
|
68
|
-
|
|
69
|
-
---
|
|
70
|
-
|
|
71
|
-
## 4. 变量从哪里来、怎么查看
|
|
72
|
-
|
|
73
|
-
```text
|
|
74
|
-
单节点测试 / 整流程运行
|
|
75
|
-
│
|
|
76
|
-
▼
|
|
77
|
-
GET /flows/{id}/debug-run → 绑定 ads_flows.debug_run_id
|
|
78
|
-
│
|
|
79
|
-
▼
|
|
80
|
-
节点成功 → 写入 flow_run_variables(name = output_variable_name)
|
|
81
|
-
│
|
|
82
|
-
▼
|
|
83
|
-
本地:flow variable pull/sync → 变量/<name>.json
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
```powershell
|
|
87
|
-
$flowDir = "D:\path\to\dazi-work\项目\<业务名>\流程\flows\MyFlow"
|
|
88
|
-
|
|
89
|
-
#
|
|
90
|
-
dazi flow
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
-
|
|
101
|
-
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
|
124
|
-
|
|
|
125
|
-
|
|
|
126
|
-
|
|
|
127
|
-
|
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
--
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
-
|
|
164
|
-
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
|
190
|
-
|
|
|
191
|
-
| `
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
|
209
|
-
|
|
|
210
|
-
| `
|
|
211
|
-
| `
|
|
212
|
-
| `
|
|
213
|
-
| `
|
|
214
|
-
| `
|
|
215
|
-
| `
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
#
|
|
224
|
-
#
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
df
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
.
|
|
236
|
-
.
|
|
237
|
-
)
|
|
238
|
-
|
|
239
|
-
output.print("
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
output.print(
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
|
329
|
-
|
|
|
330
|
-
| `
|
|
331
|
-
| `
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
|
341
|
-
|
|
|
342
|
-
| `
|
|
343
|
-
| `
|
|
344
|
-
| `
|
|
345
|
-
| `
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
|
366
|
-
|
|
|
367
|
-
|
|
|
368
|
-
|
|
|
369
|
-
|
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
dazi flow variable
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
-
|
|
406
|
-
-
|
|
1
|
+
# 流程变量系统指南
|
|
2
|
+
|
|
3
|
+
**文档 ID**: `flow/variables-guide`
|
|
4
|
+
**适用**: `dazi-vscode` 流程项目、`python-script` / `sql-query` 等代码节点
|
|
5
|
+
**概念来源**: 搭子数据流程引擎统一变量模型(对齐 devend《011》),详见 `dazi/docs/279-dazi-dataflow数据流程功能总结.md` §3
|
|
6
|
+
|
|
7
|
+
**相关文档**
|
|
8
|
+
|
|
9
|
+
- [数据流程项目开发指南](./flow-project-guide.md) — 目录、`debug_run_id`、开发循环
|
|
10
|
+
- [节点代码编写指南](./node-code-guide.md) — 各节点 `code.*` 约定
|
|
11
|
+
- [Flow 运行与测试](./run-guide.md) — `node-exec`、`variable pull/sync`
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## 1. 什么是流程变量
|
|
16
|
+
|
|
17
|
+
流程引擎把 **参数、中间表、最终结果** 统一抽象为 **变量(Variable)**,在一次 Run 内按 **变量名** 读写,而不必处处依赖画布连线传递文件路径。
|
|
18
|
+
|
|
19
|
+
| 概念 | 说明 |
|
|
20
|
+
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
21
|
+
| **变量名** | 字符串标识,如 `sales_raw`、`V1`、`销售表`;由节点配置 **`output_variable_name`** 或脚本 **`set_table_output` / `set_scalar_output`** 登记 |
|
|
22
|
+
| **变量作用域** | 绑定到某次 **`flow_runs`**;日常调试对应 **`ads_flows.debug_run_id`** |
|
|
23
|
+
| **登记时机** | 节点执行成功后,引擎读取 **`output_variable_name`**,将输出写入当前 Run 的 **`flow_run_variables`** |
|
|
24
|
+
|
|
25
|
+
**本地开发时**:变量不在 `flow.json` 里,而在调试 Run 中;CLI/扩展通过 API 拉取 schema + 预览到 **`变量/<名>.json`**。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 2. 存储类型
|
|
30
|
+
|
|
31
|
+
| 类型 | 典型场景 | 存储 | `get_variable` 行为 |
|
|
32
|
+
| ------------------- | ------------------------------------ | --------------------------------- | ---------------------------------------- |
|
|
33
|
+
| **table(表变量)** | SQL 结果、Python `result_df`、文件源 | Parquet 落盘,库中 `value` 为路径 | 自动 `pd.read_parquet` → **`DataFrame`** |
|
|
34
|
+
| **text(标量)** | 计数、标志位、质检综合分 | 库中 `value` 为字符串 | 返回 Python 原生值(str/int/float 等) |
|
|
35
|
+
|
|
36
|
+
表变量是流程开发中最常用的类型;标量多用于质检分数、状态位等。
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
## 3. 产生变量:`output_variable_name`
|
|
41
|
+
|
|
42
|
+
在 **设计器属性面板** 或 `flow.json` → 节点 `data` 中配置:
|
|
43
|
+
|
|
44
|
+
```json
|
|
45
|
+
{
|
|
46
|
+
"type": "custom",
|
|
47
|
+
"data": {
|
|
48
|
+
"type": "sql-query",
|
|
49
|
+
"output_variable_name": "sales_clean",
|
|
50
|
+
"connectionId": "..."
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
**规则**
|
|
56
|
+
|
|
57
|
+
1. 节点成功执行后,引擎以 **`output_variable_name`** 为键登记变量(表 → Parquet 路径)。
|
|
58
|
+
2. 下游节点通过 **同名** 引用该变量(SQL 表名 / Python `get_variable('sales_clean')`)。
|
|
59
|
+
3. 变量名须 **全流程内唯一**;建议英文+下划线,中文名也支持(SQL 会自动加双引号)。
|
|
60
|
+
4. 未配置 `output_variable_name` 的节点,输出不会进入变量表(仍可能有入边 Parquet,但不便于单节点调试)。
|
|
61
|
+
|
|
62
|
+
**Python 多表输出**
|
|
63
|
+
|
|
64
|
+
- 主表:赋值 **`result_df`**(与 `output_variable_name` 对应)。
|
|
65
|
+
- 附加表:**`set_table_output('other_table', df)`**(`excel-python` 主输出也须 `set_table_output` 与 `output_variable_name` 同名)。
|
|
66
|
+
|
|
67
|
+
**标量输出**:**`set_scalar_output('score', 95.5)`**,变量名由画布质检配置或业务约定。
|
|
68
|
+
|
|
69
|
+
---
|
|
70
|
+
|
|
71
|
+
## 4. 变量从哪里来、怎么查看
|
|
72
|
+
|
|
73
|
+
```text
|
|
74
|
+
单节点测试 / 整流程运行
|
|
75
|
+
│
|
|
76
|
+
▼
|
|
77
|
+
GET /flows/{id}/debug-run → 绑定 ads_flows.debug_run_id
|
|
78
|
+
│
|
|
79
|
+
▼
|
|
80
|
+
节点成功 → 写入 flow_run_variables(name = output_variable_name)
|
|
81
|
+
│
|
|
82
|
+
▼
|
|
83
|
+
本地:flow variable pull/sync → 变量/<name>.json
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
```powershell
|
|
87
|
+
$flowDir = "D:\path\to\dazi-work\项目\<业务名>\流程\flows\MyFlow"
|
|
88
|
+
|
|
89
|
+
# 先 push 再运行上游(node-exec 不读本地未提交的 code.*)
|
|
90
|
+
dazi flow node push --node <上游uuid> --dir $flowDir
|
|
91
|
+
dazi flow run node-exec --node <上游uuid> --dir $flowDir
|
|
92
|
+
|
|
93
|
+
# 拉取单个变量(列信息 + 前 10 行;成功判据之一)
|
|
94
|
+
dazi flow variable pull --name sales_clean --dir $flowDir
|
|
95
|
+
|
|
96
|
+
# 同步调试 Run 中全部变量
|
|
97
|
+
dazi flow variable sync --dir $flowDir
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
- 设计器:选中节点 → **`output_variable_name`** 旁 **📊**
|
|
101
|
+
- 资源管理器:**`变量/<名>.json`**(只读派生,勿手改后当真理源)
|
|
102
|
+
- 变量尚未产出时,占位 JSON 会提示:**先运行上游节点**
|
|
103
|
+
|
|
104
|
+
---
|
|
105
|
+
|
|
106
|
+
## 5. 管线示例:变量如何串联
|
|
107
|
+
|
|
108
|
+
典型链路 **Excel → SQL → Python**(变量名需在画布上事先约定):
|
|
109
|
+
|
|
110
|
+
```text
|
|
111
|
+
[excel-import] output_variable_name = excel_raw
|
|
112
|
+
│
|
|
113
|
+
▼
|
|
114
|
+
[sql-query] FROM excel_raw … → output_variable_name = sales_agg
|
|
115
|
+
│
|
|
116
|
+
▼
|
|
117
|
+
[python-script] get_variable('sales_agg') → result_df → output_variable_name = py_result
|
|
118
|
+
│
|
|
119
|
+
▼
|
|
120
|
+
[database-sink] input_variable_name = py_result(或依赖入边 Parquet)
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
| 步骤 | 节点 | 画布配置 | 代码如何读写变量 |
|
|
124
|
+
| ---- | --------------- | --------------------------------- | ------------------------------------------------- |
|
|
125
|
+
| 1 | `excel-import` | `output_variable_name: excel_raw` | 无代码;导入后自动登记 |
|
|
126
|
+
| 2 | `sql-query` | `output_variable_name: sales_agg` | SQL 中 **`FROM excel_raw`** |
|
|
127
|
+
| 3 | `python-script` | `output_variable_name: py_result` | **`get_variable('sales_agg')`** → **`result_df`** |
|
|
128
|
+
| 4 | `database-sink` | `input_variable_name: py_result` | 无代码;从变量或入边读表 |
|
|
129
|
+
|
|
130
|
+
---
|
|
131
|
+
|
|
132
|
+
## 6. 各节点类型:如何使用变量
|
|
133
|
+
|
|
134
|
+
### 6.1 `sql-query`(DuckDB 内存 SQL)
|
|
135
|
+
|
|
136
|
+
**消费变量**:把 **已登记在调试 Run 中的表变量名** 当作 SQL **表名** 使用。引擎会将 Parquet 注册为 DuckDB VIEW。
|
|
137
|
+
|
|
138
|
+
**产生变量**:查询结果写入 **`output_variable_name`**。
|
|
139
|
+
|
|
140
|
+
```sql
|
|
141
|
+
-- 上游节点 output_variable_name = excel_raw
|
|
142
|
+
-- 本节点 output_variable_name = sales_agg
|
|
143
|
+
|
|
144
|
+
SELECT
|
|
145
|
+
产品类别,
|
|
146
|
+
SUM(销售金额) AS 合计金额
|
|
147
|
+
FROM excel_raw
|
|
148
|
+
GROUP BY 产品类别
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
**多表 JOIN**
|
|
152
|
+
|
|
153
|
+
```sql
|
|
154
|
+
-- 变量名 orders、customers 均由上游节点产出
|
|
155
|
+
SELECT o.order_id, c.customer_name, o.amount
|
|
156
|
+
FROM orders o
|
|
157
|
+
JOIN customers c ON o.customer_id = c.customer_id
|
|
158
|
+
WHERE o.order_date >= '2026-01-01'
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
**注意**
|
|
162
|
+
|
|
163
|
+
- 变量名含中文或特殊字符时,引擎会自动加双引号(也可手写 `"销售表"`)。
|
|
164
|
+
- SQL 末尾不要加分号(引擎会去掉,避免 COPY 语法错误)。
|
|
165
|
+
- **单节点测试前**,须先运行产出 `excel_raw` 等上游变量的节点,否则 DuckDB 找不到表。
|
|
166
|
+
|
|
167
|
+
---
|
|
168
|
+
|
|
169
|
+
### 6.2 `database-source`(外部库只读)
|
|
170
|
+
|
|
171
|
+
**产生变量**:`connectionId` + `code.sql` 查外部库,结果登记为 **`output_variable_name`**。
|
|
172
|
+
**不消费** Run 内变量(直连 `ads_connections`)。
|
|
173
|
+
|
|
174
|
+
```sql
|
|
175
|
+
-- output_variable_name = dim_product
|
|
176
|
+
SELECT product_id, product_name, category
|
|
177
|
+
FROM dim_product
|
|
178
|
+
WHERE is_active = 1
|
|
179
|
+
LIMIT 50000
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
---
|
|
183
|
+
|
|
184
|
+
### 6.2b `dataspace-source`(数据空间只读)
|
|
185
|
+
|
|
186
|
+
**产生变量**:`spaceId` + `code.sql` 在空间存储引擎上查询,结果登记为 **`output_variable_name`**。
|
|
187
|
+
**不消费** Run 内变量(直连 `ads_dataspaces` + `get_storage`)。
|
|
188
|
+
|
|
189
|
+
| 配置项 | 说明 |
|
|
190
|
+
| ---------------------- | ------------------------------------------------- |
|
|
191
|
+
| `spaceId` | `ads_dataspaces.id`(`dazi-flow dataspace list`) |
|
|
192
|
+
| `output_variable_name` | 产出表变量名 |
|
|
193
|
+
|
|
194
|
+
```sql
|
|
195
|
+
-- output_variable_name = space_sales
|
|
196
|
+
SELECT *
|
|
197
|
+
FROM sales_fact
|
|
198
|
+
WHERE dt >= '2025-01-01'
|
|
199
|
+
LIMIT 100000
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
---
|
|
203
|
+
|
|
204
|
+
### 6.3 `python-script`(最常用)
|
|
205
|
+
|
|
206
|
+
**运行时注入**
|
|
207
|
+
|
|
208
|
+
| 符号 | 说明 |
|
|
209
|
+
| -------------------------------- | -------------------------------------------------- |
|
|
210
|
+
| `pd` | pandas |
|
|
211
|
+
| `df` | 入边 Parquet(**整图跑**时常有值) |
|
|
212
|
+
| `get_variable("名")` | 从当前调试 Run 按名读表/标量(**单节点测试首选**) |
|
|
213
|
+
| `result_df` | 主输出表 → 对应 **`output_variable_name`** |
|
|
214
|
+
| `set_table_output(name, df)` | 额外表变量 |
|
|
215
|
+
| `set_scalar_output(name, value)` | 标量变量 |
|
|
216
|
+
| `output.print(...)` | 运行日志(勿用裸 `print`) |
|
|
217
|
+
|
|
218
|
+
**示例 A:单节点测试(推荐写法)**
|
|
219
|
+
|
|
220
|
+
上游 `sql-query` 的 `output_variable_name = sales_agg`;本节点 `output_variable_name = py_result`。
|
|
221
|
+
|
|
222
|
+
```python
|
|
223
|
+
# -*- coding: utf-8 -*-
|
|
224
|
+
# 输入:sales_agg(上游 SQL 节点产出)
|
|
225
|
+
# 输出:py_result(本节点 output_variable_name)
|
|
226
|
+
import pandas as pd
|
|
227
|
+
|
|
228
|
+
output.print("[python-script] 开始")
|
|
229
|
+
|
|
230
|
+
# 单节点调试时 df 常为空,务必用 get_variable
|
|
231
|
+
df = get_variable("sales_agg")
|
|
232
|
+
output.print(f"输入 sales_agg shape={df.shape}, columns={list(df.columns)}")
|
|
233
|
+
|
|
234
|
+
result_df = (
|
|
235
|
+
df.groupby("产品类别", as_index=False)["合计金额"]
|
|
236
|
+
.sum()
|
|
237
|
+
.sort_values("合计金额", ascending=False)
|
|
238
|
+
)
|
|
239
|
+
output.print(f"输出 py_result shape={result_df.shape}")
|
|
240
|
+
output.print("[python-script] 完成")
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
**示例 B:整图跑 + 入边 + 附加变量**
|
|
244
|
+
|
|
245
|
+
```python
|
|
246
|
+
import pandas as pd
|
|
247
|
+
|
|
248
|
+
output.print("[python-script] 开始")
|
|
249
|
+
|
|
250
|
+
# 优先入边 df;若无数据再按变量名补
|
|
251
|
+
if df is None or df.empty:
|
|
252
|
+
df = get_variable("sales_agg")
|
|
253
|
+
else:
|
|
254
|
+
output.print(f"使用入边 df shape={df.shape}")
|
|
255
|
+
|
|
256
|
+
# 读取另一张已登记表(无需画布连线)
|
|
257
|
+
ref = get_variable("dim_product")
|
|
258
|
+
output.print(f"维表 dim_product shape={ref.shape}")
|
|
259
|
+
|
|
260
|
+
merged = df.merge(ref, on="product_id", how="left")
|
|
261
|
+
result_df = merged[merged["category"] == "A"]
|
|
262
|
+
|
|
263
|
+
# 可选:额外输出一张表
|
|
264
|
+
set_table_output("category_a_only", result_df)
|
|
265
|
+
output.print("[python-script] 完成")
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
**示例 C:标量变量**
|
|
269
|
+
|
|
270
|
+
```python
|
|
271
|
+
df = get_variable("sales_agg")
|
|
272
|
+
row_count = len(df)
|
|
273
|
+
set_scalar_output("row_count_flag", row_count)
|
|
274
|
+
result_df = df.head(100)
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### 6.4 `excel-python`
|
|
280
|
+
|
|
281
|
+
**产生变量**:读 `excel_source_path`,用 **`set_table_output`** 登记;主输出名 **必须** 与 **`output_variable_name`** 一致。
|
|
282
|
+
|
|
283
|
+
```python
|
|
284
|
+
import pandas as pd
|
|
285
|
+
|
|
286
|
+
output.print("[excel-python] 开始")
|
|
287
|
+
output.print(f"file={excel_original_filename or excel_source_path}")
|
|
288
|
+
|
|
289
|
+
df = pd.read_excel(excel_source_path, sheet_name="Sheet1")
|
|
290
|
+
output.print(f"读取 shape={df.shape}")
|
|
291
|
+
|
|
292
|
+
# 与画布 output_variable_name 同名
|
|
293
|
+
set_table_output("excel_raw", df)
|
|
294
|
+
output.print("[excel-python] 完成")
|
|
295
|
+
```
|
|
296
|
+
|
|
297
|
+
---
|
|
298
|
+
|
|
299
|
+
### 6.5 `data-quality-check`
|
|
300
|
+
|
|
301
|
+
**消费变量**:主表可用入边 **`df`**;单节点测试时 **`df` 常为空**,须用 **`get_variable`**。附加表按画布 **`attached_variables`** / 上游 `output_variable_name` 逐个读取。
|
|
302
|
+
|
|
303
|
+
```python
|
|
304
|
+
import pandas as pd
|
|
305
|
+
|
|
306
|
+
output.print("[DQ] 开始")
|
|
307
|
+
|
|
308
|
+
if df is None or df.empty:
|
|
309
|
+
df = get_variable("销售表") # 与上游 output_variable_name 完全一致
|
|
310
|
+
|
|
311
|
+
orders = get_variable("订单明细") # attached_variables 中的附加表
|
|
312
|
+
|
|
313
|
+
output.print(f"主表 shape={df.shape}, 订单 shape={orders.shape}")
|
|
314
|
+
|
|
315
|
+
# … 按 quality_config["rules"] 执行规则 …
|
|
316
|
+
|
|
317
|
+
result_df = pd.DataFrame([{"rule": "非空检查", "passed": True}])
|
|
318
|
+
set_scalar_output("quality_score", 98.5)
|
|
319
|
+
output.print("[DQ] 完成")
|
|
320
|
+
```
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
### 6.6 `database-sink`(无代码文件)
|
|
325
|
+
|
|
326
|
+
**消费变量**:画布配置 **`input_variable_name`**,从调试 Run 取表写入目标库;也可依赖入边 Parquet(未配变量名时)。
|
|
327
|
+
|
|
328
|
+
| 配置项 | 说明 |
|
|
329
|
+
| --------------------- | ------------------------------------------------ |
|
|
330
|
+
| `connectionId` | 目标 `ads_connections` |
|
|
331
|
+
| `tableName` | 目标表名 |
|
|
332
|
+
| `input_variable_name` | 可选;显式指定要写入的表变量名(如 `py_result`) |
|
|
333
|
+
|
|
334
|
+
---
|
|
335
|
+
|
|
336
|
+
### 6.6b `dataspace-sink`(无代码文件)
|
|
337
|
+
|
|
338
|
+
**消费变量**:与 `database-sink` 相同,通过 **`input_variable_name`** 或入边 Parquet 取表。
|
|
339
|
+
|
|
340
|
+
| 配置项 | 说明 |
|
|
341
|
+
| --------------------- | ------------------------------- |
|
|
342
|
+
| `spaceId` | 目标 `ads_dataspaces.id` |
|
|
343
|
+
| `tableName` | 空间内目标表(物理表名) |
|
|
344
|
+
| `mode` | `append`(默认)或 `replace` |
|
|
345
|
+
| `syncMetadata` | 写后是否同步元数据(默认 true) |
|
|
346
|
+
| `input_variable_name` | 要写入的表变量名 |
|
|
347
|
+
|
|
348
|
+
---
|
|
349
|
+
|
|
350
|
+
### 6.7 `condition`(条件分支)
|
|
351
|
+
|
|
352
|
+
条件脚本求布尔值,决定 **true/false** 分支。运行时主要注入入边 **`df`**(**不**注入 `get_variable`)。
|
|
353
|
+
|
|
354
|
+
```python
|
|
355
|
+
# code.py:表达式或单行,eval 后决定分支
|
|
356
|
+
df.shape[0] > 0 and df["amount"].sum() > 10000
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
单节点测试条件节点前,须保证 **入边上游已运行** 且连线有效;复杂判断可先用 `python-script` 写清逻辑再改为 condition。
|
|
360
|
+
|
|
361
|
+
---
|
|
362
|
+
|
|
363
|
+
## 7. `df` 与 `get_variable` 怎么选
|
|
364
|
+
|
|
365
|
+
| 场景 | 推荐 |
|
|
366
|
+
| ----------------------------- | ------------------------------------------------------------------ |
|
|
367
|
+
| **单节点测试**(`node-exec`) | **`get_variable('上游 output_variable_name')`** |
|
|
368
|
+
| **整流程 debug/preview** | 入边 **`df`** 通常已有值;仍可用 `get_variable` 读 **未连线** 的表 |
|
|
369
|
+
| **多表输入** | 一张走 `df` 或主变量,其余 **`get_variable('名')`** |
|
|
370
|
+
| **写 SQL** | 直接用 **变量名作表名**,不用 `get_variable` |
|
|
371
|
+
|
|
372
|
+
**常见错误**:单节点测试时只写 `result_df = df.groupby(...)`,但 `df` 为空 → 报错或空结果。
|
|
373
|
+
**修复**:改为 `df = get_variable("上游变量名")`,或先运行上游再测。
|
|
374
|
+
|
|
375
|
+
---
|
|
376
|
+
|
|
377
|
+
## 8. 开发调试清单
|
|
378
|
+
|
|
379
|
+
1. 打开设计器,确认各节点 **`output_variable_name`** 已填且 **不重名**。
|
|
380
|
+
2. **自上游向下** 单节点测试,或一次 **`flow run flow-exec --type debug`**。
|
|
381
|
+
3. 用 **📊** 或 **`flow variable pull --name <名>`** 核对列名与样例行(交给 AI 时附上 **`变量/<名>.json`**)。
|
|
382
|
+
4. 写下游代码时 **变量名与画布完全一致**(区分大小写;中文名含全角字符)。
|
|
383
|
+
5. 改 `output_variable_name` → **`project push --canvas`**;改 `code.*` → **`node push`**。
|
|
384
|
+
|
|
385
|
+
---
|
|
386
|
+
|
|
387
|
+
## 9. 相关命令速查
|
|
388
|
+
|
|
389
|
+
```powershell
|
|
390
|
+
# 单节点测试(会更新 debug_run_id 对应变量)
|
|
391
|
+
dazi flow run node-exec --node <uuid> --dir .
|
|
392
|
+
|
|
393
|
+
# 整流程调试
|
|
394
|
+
dazi flow run flow-exec --dir . --type debug
|
|
395
|
+
|
|
396
|
+
# 变量
|
|
397
|
+
dazi flow variable pull --name sales_agg --dir .
|
|
398
|
+
dazi flow variable sync --dir .
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
---
|
|
402
|
+
|
|
403
|
+
## 10. 延伸阅读
|
|
404
|
+
|
|
405
|
+
- 搭子功能总览:`dazi/docs/279-dazi-dataflow数据流程功能总结.md` §3
|
|
406
|
+
- devend 变量重构:`devend/docs/20251201-009-变量系统重构.md`
|
|
407
|
+
- Excel→SQL→Python 端到端案例:[流程开发最佳实践(VS-flow0 案例)](./流程开发最佳实践-VS-flow0案例.md)
|