This is an automated email from the ASF dual-hosted git repository.
davidzollo pushed a commit to branch dev
in repository https://gitbox.apache.org/repos/asf/seatunnel.git
The following commit(s) were added to refs/heads/dev by this push:
new 67de2f221f [Docs] Add sink write mode guidance (#11589)
67de2f221f is described below
commit 67de2f221ff75a02213007273c2802b0d0312145
Author: danielnadean <[email protected]>
AuthorDate: Wed Jul 29 23:46:27 2026 +0800
[Docs] Add sink write mode guidance (#11589)
Co-authored-by: davidzollo <[email protected]>
---
.../common-options/sink-common-options.md | 4 +-
.../connectors/common-options/sink-write-modes.md | 181 +++++++++++++++++++++
docs/en/connectors/connector-faq.md | 5 +-
docs/en/faq.md | 5 +
docs/sidebars.js | 1 +
.../common-options/sink-common-options.md | 4 +-
.../connectors/common-options/sink-write-modes.md | 181 +++++++++++++++++++++
docs/zh/connectors/connector-faq.md | 5 +-
docs/zh/faq.md | 5 +
9 files changed, 385 insertions(+), 6 deletions(-)
diff --git a/docs/en/connectors/common-options/sink-common-options.md
b/docs/en/connectors/common-options/sink-common-options.md
index 3b4e98b947..295524f28a 100644
--- a/docs/en/connectors/common-options/sink-common-options.md
+++ b/docs/en/connectors/common-options/sink-common-options.md
@@ -6,6 +6,9 @@ sidebar_position: 4
> Common parameters of sink connectors
+For sink write mode selection, automatic SQL generation, `schema_save_mode`,
`data_save_mode`,
+`custom_sql`, and `enable_upsert`, see [Sink Write Modes and Save
Modes](sink-write-modes.md).
+
:::caution warn
The old configuration name `source_table_name` is deprecated, please migrate
to the new name `plugin_input` as soon as possible.
@@ -61,4 +64,3 @@ sink {
> If the job only have one source and one(or zero) transform and one sink, You
> do not need to specify `plugin_input` and `plugin_output` for connector.
> If the number of any operator in source, transform and sink is greater than
> 1, you must specify the `plugin_input` and `plugin_output` for each
> connector in the job.
-
diff --git a/docs/en/connectors/common-options/sink-write-modes.md
b/docs/en/connectors/common-options/sink-write-modes.md
new file mode 100644
index 0000000000..06b2d871f3
--- /dev/null
+++ b/docs/en/connectors/common-options/sink-write-modes.md
@@ -0,0 +1,181 @@
+---
+sidebar_position: 3
+---
+
+# Sink Write Modes and Save Modes
+
+Sink configuration has two different decisions that are easy to mix together:
+
+- **Write mode** decides how SeaTunnel writes each row to the target system.
+- **Save mode** decides how SeaTunnel handles the existing target table,
index, directory, or data before the job starts writing rows.
+
+Read this page when you are choosing among `generate_sink_sql`, `query`,
`schema_save_mode`, `data_save_mode`, `custom_sql`, `primary_keys`, or
`enable_upsert`.
+
+## Quick Decision Table
+
+| Goal | Prefer | Notes |
+|------|--------|-------|
+| Let SeaTunnel generate INSERT / UPSERT / UPDATE / DELETE SQL for a JDBC
target | `generate_sink_sql = true` with `database`, `table`, and usually
`primary_keys` | This is a JDBC Sink feature. It also enables save mode
handling for JDBC because SeaTunnel can resolve the target catalog table. |
+| Fully control the JDBC write statement | `query = "INSERT ... VALUES (?,
...)"` | Do not combine with `generate_sink_sql = true`. In this mode JDBC Sink
does not execute `schema_save_mode`, `data_save_mode`, or `custom_sql`. |
+| Create a missing target table or fail when it is missing |
`schema_save_mode` | Only works for sinks that expose save mode options and can
create or inspect the target through a catalog. |
+| Keep, clear, or reject existing target data before writing |
`data_save_mode` | Supported values depend on the connector. File sinks usually
support only `DROP_DATA`, `APPEND_DATA`, and `ERROR_WHEN_DATA_EXISTS`. |
+| Run a custom SQL statement before the job writes data | `data_save_mode =
"CUSTOM_PROCESSING"` and `custom_sql` | Only for connectors that expose both
options. This is a pre-write hook, not the per-row write SQL. |
+| Use database-native upsert in JDBC Sink | `generate_sink_sql = true`,
`primary_keys`, `enable_upsert = true` | Without a usable primary key or unique
key, JDBC generated SQL falls back to plain INSERT. |
+| Write to object storage or file systems | Check the specific File Sink
option table | File sinks do not use `generate_sink_sql`. Some file connectors
expose save mode options; others do not. |
+
+## JDBC: `generate_sink_sql` vs `query`
+
+JDBC Sink has two mutually exclusive write modes.
+
+| Mode | Required options | Save modes applied? | Typical use case |
+|------|------------------|---------------------|------------------|
+| Generated SQL | `generate_sink_sql = true`, `database`, and normally `table`
| Yes, when the target catalog table can be resolved | Most database sink jobs,
CDC writes, automatic table creation, upsert, update, and delete |
+| Custom SQL | `query = "INSERT ... VALUES (?, ...)"` | No | You must control
the exact target SQL and accept that save mode handling is skipped |
+
+Do not configure both `generate_sink_sql = true` and `query`.
+
+When `generate_sink_sql = true`, configure `primary_keys` if the sink must
process UPDATE, DELETE, or upsert records. If `primary_keys` is omitted,
SeaTunnel tries to inherit a primary key from upstream catalog metadata, then
the first unique key. If neither exists, generated SQL becomes plain INSERT.
+
+## Save Mode Semantics
+
+### `schema_save_mode`
+
+`schema_save_mode` controls the target structure before row writing starts.
+
+| Value | Behavior |
+|-------|----------|
+| `RECREATE_SCHEMA` | Create the target if it does not exist. If it exists,
drop and recreate it. |
+| `CREATE_SCHEMA_WHEN_NOT_EXIST` | Create the target only when it does not
exist. |
+| `ERROR_WHEN_SCHEMA_NOT_EXIST` | Fail when the target does not exist. |
+| `IGNORE` | Skip structure handling. |
+
+For database sinks, the target is usually a table. For file sinks, the target
is usually a path or directory.
+
+### `data_save_mode`
+
+`data_save_mode` controls existing target data before row writing starts.
+
+| Value | Behavior |
+|-------|----------|
+| `DROP_DATA` | Keep the structure and clear existing data. |
+| `APPEND_DATA` | Keep existing data and append new data. |
+| `CUSTOM_PROCESSING` | Execute `custom_sql` before writing. Only supported by
connectors that expose both options. |
+| `ERROR_WHEN_DATA_EXISTS` | Fail when existing data is found. |
+
+Connector support is not universal. Always use the option table of the
connector version you run as the final source of truth.
+
+## Connector Support Boundaries
+
+### JDBC-family sinks
+
+The JDBC Sink and JDBC-based sink pages such as MySQL, PostgreSQL, Oracle, and
SQL Server use the JDBC write-mode model:
+
+- `generate_sink_sql` is available.
+- `query` is available.
+- `schema_save_mode` and `data_save_mode` are available in generated SQL mode.
+- `custom_sql` is only executed when save mode handling runs.
+- `enable_upsert` only matters after SeaTunnel has a usable primary key or
unique key.
+
+See [JDBC Sink](../sink/Jdbc.md) for the complete option reference and
examples.
+
+### Doris Sink
+
+Doris Sink supports `schema_save_mode`, `data_save_mode`, `custom_sql`, and
`save_mode_create_template`, but it does not use JDBC `generate_sink_sql`.
+
+For CDC DELETE events, Doris also needs Doris-side delete support and the
connector option `sink.enable-delete` when applicable. See [Doris
Sink](../sink/Doris.md).
+
+### File and object-storage sinks
+
+File sinks write files, so they do not use `generate_sink_sql`, `query`, or
database upsert.
+
+Current connector support differs by file connector:
+
+| Connector | Save mode options exposed? | Notes |
+|-----------|----------------------------|-------|
+| LocalFile | Yes | Handles existing local directories and files. |
+| HdfsFile | Yes | Handles existing HDFS directories and files. |
+| FtpFile | Yes | Handles existing FTP directories and files. |
+| SftpFile | Yes | Handles existing SFTP directories and files. |
+| S3File | Yes | Handles existing S3 paths and objects through the file sink
save mode flow. |
+| OssFile | Yes | Handles existing OSS paths and objects through the file sink
save mode flow. |
+| ObsFile | No | The current sink option rule does not expose
`schema_save_mode` or `data_save_mode`. |
+| CosFile | No | The current sink option rule does not expose
`schema_save_mode` or `data_save_mode`. |
+
+If a file connector page does not list `schema_save_mode` or `data_save_mode`,
do not assume the option is accepted by that connector.
+
+## Examples
+
+### JDBC generated SQL with save modes
+
+```hocon
+sink {
+ Jdbc {
+ url = "jdbc:postgresql://localhost:5432/sales"
+ driver = "org.postgresql.Driver"
+ username = "postgres"
+ password = "change_me"
+
+ generate_sink_sql = true
+ database = "sales"
+ table = "public.orders"
+ primary_keys = ["id"]
+
+ schema_save_mode = "CREATE_SCHEMA_WHEN_NOT_EXIST"
+ data_save_mode = "APPEND_DATA"
+ }
+}
+```
+
+### JDBC custom SQL without save modes
+
+```hocon
+sink {
+ Jdbc {
+ url = "jdbc:mysql://localhost:3306/sales"
+ driver = "com.mysql.cj.jdbc.Driver"
+ username = "root"
+ password = "change_me"
+
+ query = "INSERT INTO orders(id, amount) VALUES (?, ?)"
+ }
+}
+```
+
+In this mode, JDBC Sink writes rows through `query`; it does not execute
`schema_save_mode`, `data_save_mode`, or `custom_sql`.
+
+### S3File clear existing data before writing
+
+```hocon
+sink {
+ S3File {
+ path = "/warehouse/orders"
+ bucket = "s3a://example-bucket"
+ fs.s3a.endpoint = "s3.amazonaws.com"
+ fs.s3a.aws.credentials.provider =
"org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider"
+ access_key = "..."
+ secret_key = "..."
+
+ file_format_type = "json"
+ schema_save_mode = "CREATE_SCHEMA_WHEN_NOT_EXIST"
+ data_save_mode = "DROP_DATA"
+ }
+}
+```
+
+## Troubleshooting
+
+### `generate_sink_sql = true` still writes only INSERT
+
+Check whether SeaTunnel has a usable key. Configure `primary_keys` explicitly
when you expect upsert, update, or delete behavior.
+
+### `custom_sql` did not run in JDBC Sink
+
+Check whether the sink uses `query`. JDBC custom query mode does not apply
save mode handling, so `custom_sql` is skipped.
+
+### A file sink rejects `data_save_mode`
+
+Check the specific connector option table. `S3File`, `OssFile`, `HdfsFile`,
`FtpFile`, `SftpFile`, and `LocalFile` expose file save mode options. `ObsFile`
and `CosFile` currently do not.
+
+### I only want to create the target table
+
+Save mode runs as part of a sink job before row writing. SeaTunnel does not
provide a standalone "DDL only" mode through `schema_save_mode`. If the job has
no rows, the sink may still initialize, but this is not a replacement for a
dedicated schema-management workflow.
diff --git a/docs/en/connectors/connector-faq.md
b/docs/en/connectors/connector-faq.md
index a47544ba0b..6626404542 100644
--- a/docs/en/connectors/connector-faq.md
+++ b/docs/en/connectors/connector-faq.md
@@ -62,5 +62,6 @@ Change Data Capture connectors read real-time change events
(INSERT / UPDATE / D
## Tips for Finding Answers
1. **Connector-specific issues** → go directly to the connector's page and
scroll to its **FAQ** section.
-2. **Cross-connector topics** (e.g., "does SeaTunnel support CDC?", "what is
`schema_save_mode`?") → see the [General FAQ](../faq.md).
-3. **Still stuck?** → search the [GitHub
Issues](https://github.com/apache/seatunnel/issues) or reach out via the
[mailing list](https://lists.apache.org/[email protected]).
+2. **Cross-connector sink write topics** (e.g., "`generate_sink_sql` vs
`query`", "`schema_save_mode`", "`data_save_mode`", or `enable_upsert`) → see
[Sink Write Modes and Save Modes](./common-options/sink-write-modes.md).
+3. **Other cross-connector topics** (e.g., "does SeaTunnel support CDC?") →
see the [General FAQ](../faq.md).
+4. **Still stuck?** → search the [GitHub
Issues](https://github.com/apache/seatunnel/issues) or reach out via the
[mailing list](https://lists.apache.org/[email protected]).
diff --git a/docs/en/faq.md b/docs/en/faq.md
index 4000e8c268..e17aba6ec8 100644
--- a/docs/en/faq.md
+++ b/docs/en/faq.md
@@ -47,6 +47,7 @@ Before starting an integration task, you can select different
handling schemes f
- **`ERROR_WHEN_SCHEMA_NOT_EXIST`**: Throws an error if the table does not
exist.
- **`IGNORE`**: Ignores table handling.
Many connectors currently support automatic table creation. Refer to the
specific connector documentation, such as [Jdbc
sink](./connectors/sink/Jdbc.md#schema_save_mode-enum), for more information.
+ For cross-sink behavior and the relationship with `generate_sink_sql`, see
[Sink Write Modes and Save
Modes](./connectors/common-options/sink-write-modes.md).
## Does SeaTunnel support handling existing data before starting a data
integration task?
Yes, you can specify different processing schemes for existing data on the
target side before starting an integration task, controlled via the
`data_save_mode` parameter. Available options include:
@@ -57,6 +58,10 @@ Yes, you can specify different processing schemes for
existing data on the targe
Many connectors support handling existing data; please refer to the
respective connector documentation, such as [Jdbc
sink](https://seatunnel.apache.org/docs/connectors/sink/Jdbc#data_save_mode-enum).
Note: for JDBC sink, when sink `query` is configured (custom write SQL),
save mode handling is currently not applied, so
`CUSTOM_PROCESSING`/`custom_sql` will not be executed.
+ For connector support boundaries and file/object-storage sink behavior, see
[Sink Write Modes and Save
Modes](./connectors/common-options/sink-write-modes.md).
+
+## Should I use `generate_sink_sql` or `query` in JDBC Sink?
+Use `generate_sink_sql = true` with `database`, `table`, and usually
`primary_keys` when you want SeaTunnel to generate INSERT, UPSERT, UPDATE, and
DELETE statements and apply save mode handling. Use `query` only when you must
fully control the per-row SQL statement. Do not configure both modes. For the
complete decision table, see [Sink Write Modes and Save
Modes](./connectors/common-options/sink-write-modes.md).
## Does SeaTunnel support exactly-once consistency?
SeaTunnel supports exactly-once consistency for some data sources, such as
MySQL and PostgreSQL, ensuring data consistency during integration. Note that
exactly-once consistency depends on the capabilities of the underlying database.
diff --git a/docs/sidebars.js b/docs/sidebars.js
index bb3ce797aa..1a51cd53c8 100644
--- a/docs/sidebars.js
+++ b/docs/sidebars.js
@@ -134,6 +134,7 @@ const sidebars = {
"label": "Common Options",
"items": [
"connectors/common-options/source-common-options",
+ "connectors/common-options/sink-write-modes",
"connectors/common-options/sink-common-options"
]
},
diff --git a/docs/zh/connectors/common-options/sink-common-options.md
b/docs/zh/connectors/common-options/sink-common-options.md
index c3f52cebd8..4c9223ed8f 100644
--- a/docs/zh/connectors/common-options/sink-common-options.md
+++ b/docs/zh/connectors/common-options/sink-common-options.md
@@ -6,6 +6,9 @@ sidebar_position: 4
> Sink 连接器常用参数
+关于 Sink 写入模式、自动生成 SQL、`schema_save_mode`、`data_save_mode`、`custom_sql`、
+`enable_upsert` 的选择,请先阅读 [Sink 写入模式与 Save Mode](sink-write-modes.md)。
+
:::caution 警告
旧的配置名称 `source_table_name` 已经过时,请尽快迁移到新名称 `plugin_input`。
@@ -70,4 +73,3 @@ sink {
> 如果作业只有一个 source 和一个(或零个)transform 和一个 sink ,则不需要为连接器指定 `plugin_input` 和
> `plugin_output`。
> 如果 source 、transform 和 sink 中任意运算符的数量大于 1,则必须为作业中的每个连接器指定 `plugin_input` 和
> `plugin_output`
-
diff --git a/docs/zh/connectors/common-options/sink-write-modes.md
b/docs/zh/connectors/common-options/sink-write-modes.md
new file mode 100644
index 0000000000..b486cd9e4b
--- /dev/null
+++ b/docs/zh/connectors/common-options/sink-write-modes.md
@@ -0,0 +1,181 @@
+---
+sidebar_position: 3
+---
+
+# Sink 写入模式与 Save Mode
+
+Sink 配置里有两个容易混淆的决策:
+
+- **写入模式**决定 SeaTunnel 如何把每一行数据写到目标端。
+- **Save Mode**决定 SeaTunnel 在开始写入数据前,如何处理目标端已经存在的表、索引、目录或数据。
+
+当你需要在
`generate_sink_sql`、`query`、`schema_save_mode`、`data_save_mode`、`custom_sql`、`primary_keys`、`enable_upsert`
之间做选择时,可以先看这一页。
+
+## 快速决策表
+
+| 目标 | 优先选择 | 说明 |
+|------|----------|------|
+| 让 SeaTunnel 为 JDBC 目标端生成 INSERT / UPSERT / UPDATE / DELETE SQL |
`generate_sink_sql = true`,并配置 `database`、`table`,通常还要配置 `primary_keys` | 这是
JDBC Sink 的能力。SeaTunnel 能解析目标 Catalog 表时,也可以执行 save mode 和自动建表。 |
+| 完全控制 JDBC 写入 SQL | `query = "INSERT ... VALUES (?, ...)"` | 不要和
`generate_sink_sql = true` 同时配置。JDBC Sink 在这个模式下不会执行
`schema_save_mode`、`data_save_mode` 或 `custom_sql`。 |
+| 目标表不存在时自动创建,或不存在时报错 | `schema_save_mode` | 仅适用于显式暴露 save mode 参数,并且能通过
Catalog 创建或检查目标端的 Sink。 |
+| 写入前保留、清空或检查目标端已有数据 | `data_save_mode` | 支持值取决于具体 connector。File Sink 通常只支持
`DROP_DATA`、`APPEND_DATA`、`ERROR_WHEN_DATA_EXISTS`。 |
+| 写入数据前先执行一条自定义 SQL | `data_save_mode = "CUSTOM_PROCESSING"` 和 `custom_sql` |
仅适用于同时暴露这两个参数的 connector。这是写入前钩子,不是逐行写入 SQL。 |
+| JDBC Sink 使用数据库原生 Upsert | `generate_sink_sql =
true`、`primary_keys`、`enable_upsert = true` | 没有可用主键或唯一键时,JDBC 自动生成 SQL 会退化为普通
INSERT。 |
+| 写入对象存储或文件系统 | 查看具体 File Sink 参数表 | File Sink 不使用 `generate_sink_sql`。部分文件
connector 暴露 save mode,部分不暴露。 |
+
+## JDBC:`generate_sink_sql` 与 `query`
+
+JDBC Sink 有两种互斥的写入模式。
+
+| 模式 | 必需参数 | 是否执行 Save Mode | 典型场景 |
+|------|----------|-------------------|----------|
+| 自动生成 SQL | `generate_sink_sql = true`、`database`,通常还有 `table` | 是,前提是能解析目标
Catalog 表 | 大多数数据库写入、CDC 写入、自动建表、upsert、update、delete |
+| 自定义 SQL | `query = "INSERT ... VALUES (?, ...)"` | 否 | 必须完全控制目标 SQL,并接受跳过
save mode 处理 |
+
+不要同时配置 `generate_sink_sql = true` 和 `query`。
+
+使用 `generate_sink_sql = true` 时,如果目标端需要处理 UPDATE、DELETE 或 upsert 记录,请配置
`primary_keys`。如果没有显式配置 `primary_keys`,SeaTunnel 会尝试从上游 Catalog
元数据继承主键,再尝试第一组唯一键;仍然没有可用键时,会退化为普通 INSERT。
+
+## Save Mode 语义
+
+### `schema_save_mode`
+
+`schema_save_mode` 控制写入前如何处理目标结构。
+
+| 值 | 行为 |
+|----|------|
+| `RECREATE_SCHEMA` | 目标不存在时创建;目标已存在时删除后重建。 |
+| `CREATE_SCHEMA_WHEN_NOT_EXIST` | 仅在目标不存在时创建。 |
+| `ERROR_WHEN_SCHEMA_NOT_EXIST` | 目标不存在时报错。 |
+| `IGNORE` | 跳过结构处理。 |
+
+对于数据库 Sink,目标通常是表;对于文件 Sink,目标通常是路径或目录。
+
+### `data_save_mode`
+
+`data_save_mode` 控制写入前如何处理目标端已有数据。
+
+| 值 | 行为 |
+|----|------|
+| `DROP_DATA` | 保留结构并清空已有数据。 |
+| `APPEND_DATA` | 保留已有数据并追加写入。 |
+| `CUSTOM_PROCESSING` | 写入前执行 `custom_sql`。仅适用于同时暴露这两个参数的 connector。 |
+| `ERROR_WHEN_DATA_EXISTS` | 发现已有数据时报错。 |
+
+这些参数不是所有 connector 都支持。最终请以你正在使用版本的具体 connector 参数表为准。
+
+## Connector 支持边界
+
+### JDBC 系列 Sink
+
+JDBC Sink 以及 MySQL、PostgreSQL、Oracle、SQL Server 等 JDBC 系列 Sink 页面使用同一套 JDBC
写入模式:
+
+- 支持 `generate_sink_sql`。
+- 支持 `query`。
+- 自动生成 SQL 模式下支持 `schema_save_mode` 和 `data_save_mode`。
+- `custom_sql` 只有在 save mode 处理真正执行时才会执行。
+- `enable_upsert` 只有在 SeaTunnel 拿到可用主键或唯一键后才有意义。
+
+完整参数和示例请看 [JDBC Sink](../sink/Jdbc.md)。
+
+### Doris Sink
+
+Doris Sink 支持 `schema_save_mode`、`data_save_mode`、`custom_sql` 和
`save_mode_create_template`,但不使用 JDBC 的 `generate_sink_sql`。
+
+如果要处理 CDC DELETE 事件,还需要 Doris 侧支持删除能力,并按场景配置 connector 的
`sink.enable-delete`。详见 [Doris Sink](../sink/Doris.md)。
+
+### File 与对象存储 Sink
+
+File Sink 写的是文件,因此不使用 `generate_sink_sql`、`query` 或数据库 upsert。
+
+当前不同文件 connector 的支持边界如下:
+
+| Connector | 是否暴露 Save Mode 参数 | 说明 |
+|-----------|-------------------------|------|
+| LocalFile | 是 | 处理本地目录和文件。 |
+| HdfsFile | 是 | 处理 HDFS 目录和文件。 |
+| FtpFile | 是 | 处理 FTP 目录和文件。 |
+| SftpFile | 是 | 处理 SFTP 目录和文件。 |
+| S3File | 是 | 通过 File Sink save mode 流程处理 S3 路径和对象。 |
+| OssFile | 是 | 通过 File Sink save mode 流程处理 OSS 路径和对象。 |
+| ObsFile | 否 | 当前 sink option rule 没有暴露 `schema_save_mode` 或
`data_save_mode`。 |
+| CosFile | 否 | 当前 sink option rule 没有暴露 `schema_save_mode` 或
`data_save_mode`。 |
+
+如果某个文件 connector 页面没有列出 `schema_save_mode` 或 `data_save_mode`,不要默认认为该
connector 可以接收这些参数。
+
+## 示例
+
+### JDBC 自动生成 SQL 并使用 Save Mode
+
+```hocon
+sink {
+ Jdbc {
+ url = "jdbc:postgresql://localhost:5432/sales"
+ driver = "org.postgresql.Driver"
+ username = "postgres"
+ password = "change_me"
+
+ generate_sink_sql = true
+ database = "sales"
+ table = "public.orders"
+ primary_keys = ["id"]
+
+ schema_save_mode = "CREATE_SCHEMA_WHEN_NOT_EXIST"
+ data_save_mode = "APPEND_DATA"
+ }
+}
+```
+
+### JDBC 自定义 SQL,不执行 Save Mode
+
+```hocon
+sink {
+ Jdbc {
+ url = "jdbc:mysql://localhost:3306/sales"
+ driver = "com.mysql.cj.jdbc.Driver"
+ username = "root"
+ password = "change_me"
+
+ query = "INSERT INTO orders(id, amount) VALUES (?, ?)"
+ }
+}
+```
+
+在这个模式下,JDBC Sink 只通过 `query` 写入每一行,不会执行 `schema_save_mode`、`data_save_mode` 或
`custom_sql`。
+
+### S3File 写入前清空已有数据
+
+```hocon
+sink {
+ S3File {
+ path = "/warehouse/orders"
+ bucket = "s3a://example-bucket"
+ fs.s3a.endpoint = "s3.amazonaws.com"
+ fs.s3a.aws.credentials.provider =
"org.apache.hadoop.fs.s3a.SimpleAWSCredentialsProvider"
+ access_key = "..."
+ secret_key = "..."
+
+ file_format_type = "json"
+ schema_save_mode = "CREATE_SCHEMA_WHEN_NOT_EXIST"
+ data_save_mode = "DROP_DATA"
+ }
+}
+```
+
+## 故障排查
+
+### 配了 `generate_sink_sql = true` 但仍然只是 INSERT
+
+检查 SeaTunnel 是否拿到了可用 key。需要 upsert、update 或 delete 时,建议显式配置 `primary_keys`。
+
+### JDBC Sink 的 `custom_sql` 没有执行
+
+检查 Sink 是否配置了 `query`。JDBC 自定义 query 模式不会执行 save mode 处理,因此会跳过 `custom_sql`。
+
+### File Sink 不接受 `data_save_mode`
+
+检查具体 connector
参数表。`S3File`、`OssFile`、`HdfsFile`、`FtpFile`、`SftpFile`、`LocalFile` 暴露文件 save
mode 参数;`ObsFile` 和 `CosFile` 当前未暴露。
+
+### 我只想建表,不想抽取数据
+
+Save mode 是 Sink 作业写入前的一部分,SeaTunnel 目前没有通过 `schema_save_mode` 提供独立的“只执行
DDL”模式。如果作业没有数据,Sink 仍可能完成初始化,但这不能替代专门的 schema 管理流程。
diff --git a/docs/zh/connectors/connector-faq.md
b/docs/zh/connectors/connector-faq.md
index 8f429c183d..d8089e9186 100644
--- a/docs/zh/connectors/connector-faq.md
+++ b/docs/zh/connectors/connector-faq.md
@@ -60,5 +60,6 @@ CDC(Change Data Capture)连接器从数据库事务日志中读取实时变
## 查找答案的技巧
1. **连接器相关问题** → 直接进入对应连接器页面,滚动到 **FAQ** 章节。
-2. **跨连接器主题**(例如「SeaTunnel 是否支持 CDC?」「`schema_save_mode` 是什么?」)→
参阅[通用常见问题](../faq.md)。
-3. **仍未解决?** → 在 [GitHub Issues](https://github.com/apache/seatunnel/issues)
中搜索,或通过[邮件列表](https://lists.apache.org/[email protected])联系社区。
+2. **跨 Sink 写入主题**(例如「`generate_sink_sql` 和 `query` 怎么选?」「`schema_save_mode`
是什么?」「`data_save_mode` 是否支持?」「`enable_upsert` 什么时候生效?」)→ 参阅 [Sink 写入模式与 Save
Mode](./common-options/sink-write-modes.md)。
+3. **其他跨连接器主题**(例如「SeaTunnel 是否支持 CDC?」)→ 参阅[通用常见问题](../faq.md)。
+4. **仍未解决?** → 在 [GitHub Issues](https://github.com/apache/seatunnel/issues)
中搜索,或通过[邮件列表](https://lists.apache.org/[email protected])联系社区。
diff --git a/docs/zh/faq.md b/docs/zh/faq.md
index 7fbcc8208f..ff7f5e619f 100644
--- a/docs/zh/faq.md
+++ b/docs/zh/faq.md
@@ -52,6 +52,7 @@ SeaTunnel 支持增量数据同步。例如通过 CDC 连接器实现对数据
- **`ERROR_WHEN_SCHEMA_NOT_EXIST`**:当表不存在时会报错。
- **`IGNORE`**:忽略对表的处理。
目前很多 connector 已经支持了自动建表,请参考对应的 connector 文档,这里拿 Jdbc 举例,请参考 [Jdbc
sink](./connectors/sink/Jdbc.md#schema_save_mode-enum)
+ 跨 Sink 的行为边界,以及它和 `generate_sink_sql` 的关系,请参考 [Sink 写入模式与 Save
Mode](./connectors/common-options/sink-write-modes.md)。
## SeaTunnel 是否支持数据同步任务开始前对已有数据进行处理?
在同步任务启动之前,可以为目标端已有的数据选择不同的处理方案。是通过 `data_save_mode` 参数来控制的。
@@ -63,6 +64,10 @@ SeaTunnel 支持增量数据同步。例如通过 CDC 连接器实现对数据
目前很多 connector 已经支持了对已有数据进行处理,请参考对应的 connector 文档,这里拿 Jdbc 举例,请参考 [Jdbc
sink](https://seatunnel.apache.org/docs/connectors/sink/Jdbc#data_save_mode-enum)
注意:对于 JDBC sink,当 sink 配置了 `query`(自定义写入 SQL)时,当前不会执行 save mode 处理,因此
`CUSTOM_PROCESSING`/`custom_sql` 不会生效。
+ 具体 connector 支持边界,以及 File/Object Storage Sink 的差异,请参考 [Sink 写入模式与 Save
Mode](./connectors/common-options/sink-write-modes.md)。
+
+## JDBC Sink 应该使用 `generate_sink_sql` 还是 `query`?
+当你希望 SeaTunnel 自动生成 INSERT、UPSERT、UPDATE、DELETE,并且需要 save mode 或自动建表时,优先使用
`generate_sink_sql = true`,并配置 `database`、`table`,通常还要配置
`primary_keys`。只有在必须完全控制逐行写入 SQL 时才使用 `query`。不要同时配置两种模式。完整决策表请参考 [Sink 写入模式与
Save Mode](./connectors/common-options/sink-write-modes.md)。
## SeaTunnel 是否支持精确一致性管理?
SeaTunnel 支持一部分数据源的精确一致性,例如支持 MySQL、PostgreSQL
等数据库的事务写入,确保数据在同步过程中的一致性,另外精确一致性也要看数据库本身是否可以支持