# LOAD DATA INFILE
`LOAD DATA INFILE`语句能高效地将文件中的数据读取到数据库中的表中。`LOAD DATA INFILE` 与 `SELECT INTO OUTFILE`互补。要将数据从 table导出到文件,请使用[SELECT INTO OUTFILE](../dql/SELECT_INTO_STATEMENT.md)。要将文件数据导入到 table 中,请使用`LOAD DATA INFILE`。注意,导入的文件schema顺序应与表的schema顺序一致。
```{note}
无论何种load_mode,INFILE 的 filePath既可以是单个文件名,也可以是目录,也可以使用`*`通配符。
- load_mode=cluster的具体格式等价于`DataFrameReader.read.load(String)`,可以使用spark shell来read你想要的文件路径,确认能否读入成功。如果目录中存在多格式的文件,只会选择 LoadDataInfileOptionsList 中指定的FORMAT格式文件。
- load_mode=local则使用glob选择出符合的所有文件,不会检查单个文件的格式,所以,请保证满足条件的文件都是csv格式,建议使用`*.csv`限制文件格式。
```
## Syntax
```sql
LoadDataInfileStmt
::= 'LOAD' 'DATA' 'INFILE' filePath 'INTO' 'TABLE' tableName LoadDataInfileOptionsList
filePath
::= URI
tableName
::= string_literal
LoadDataInfileOptionsList
::= 'OPTIONS' '(' LoadDataInfileOptionItem (',' LoadDataInfileOptionItem)* ')'
LoadDataInfileOptionItem
::= 'DELIMITER' '=' string_literal
|'HEADER' '=' bool_literal
|'NULL_VALUE' '=' string_literal
|'FORMAT' '=' string_literal
|'QUOTE' '=' string_literal
|'MODE' '=' string_literal
|'DEEP_COPY' '=' bool_literal
|'LOAD_MODE' '=' string_literal
|'THREAD' '=' int_literal
URI
::= 'file://FilePathPattern'
|'hdfs://FilePathPattern'
|'hive://[db.]table'
|'FilePathPattern'
FilePathPattern
::= string_literal
```
其中`FilePathPattern`支持通配符`*`,比如可以设成`/test/*.csv`,匹配规则和`ls FilePathPattern`一致。
下表展示了`LOAD DATA INFILE`语句的配置项。
| 配置项 | 类型 | 默认值 | 描述 |
| ----------- | ------- | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| delimiter | String | , | 列分隔符,默认为`,`。 |
| header | Boolean | true | 是否包含表头, 默认为`true` 。 |
| null_value | String | null | NULL值,默认填充`"null"`。加载时,遇到null_value的字符串将被转换为`"null"`,插入表中。 |
| format | String | csv | 导入文件的格式:
`csv`: 不显示指明format时,默认为该值。
`parquet`: 集群版还支持导入parquet格式文件,单机版不支持。 |
| quote | String | " | 输入数据的包围字符串。字符串长度<=1。
load_mode=`cluster`默认为双引号`"`。配置包围字符后,被包围字符包围的内容将作为一个整体解析。例如,当配置包围字符串为"#"时, `1, 1.0, #This is a string field, even there is a comma#, normal_string`将为解析为三个filed,第一个是整数1,第二个是浮点1.0,第三个是一个字符串,第四个虽然没有quote,但也是一个字符串。
**local_mode=`local`默认为`\0`,也可使用空字符串赋值,不处理包围字符。** |
| mode | String | "error_if_exists" | 导入模式:
`error_if_exists`: 仅离线模式可用,若离线表已有数据则报错。
`overwrite`: 仅离线模式可用,数据将覆盖离线表数据。
`append`:离线在线均可用,若文件已存在,数据将追加到原文件后面。
**local_mode=`local`默认为`append`** |
| deep_copy | Boolean | true | `deep_copy=false`仅支持离线load, 可以指定`INFILE` Path为该表的离线存储地址,从而不需要硬拷贝。 |
| load_mode | String | cluster | `load_mode='local'`仅支持从csv本地文件导入在线存储, 它通过本地客户端同步插入数据;
`load_mode='cluster'`仅支持集群版, 通过spark插入数据,支持同步或异步模式
local模式的使用限制见[local导入模式说明](#local导入模式说明) |
| thread | Integer | 1 | 仅在本地文件导入时生效,即`load_mode='local'`或者单机版,表示本地插入数据的线程数。 最大值为`50`。 |
| writer_type | String | single | 集群版在线导入中插入数据的writer类型。可选值为`single`和`batch`,默认为`single`。`single`表示数据即读即写,节省内存。`batch`则是将整个rdd分区读完,确认数据类型有效性后,再写入集群,需要更多内存。在部分情况下,`batch`模式有利于筛选未写入的数据,方便重试这部分数据。 |
| put_if_absent | Boolean | false | 在源数据无重复行也不与表中已有数据重复时,可以使用此选项避免插入重复数据,特别是job失败后可以重试。等价于使用`INSERT OR IGNORE`。更多详情见下文。 |
```{note}
在集群版中,`LOAD DATA INFILE`语句会根据当前执行模式(execute_mode)决定将数据导入到在线或离线存储。单机版中没有存储区别,只会导入到在线存储中,同时也不支持`deep_copy`选项。
具体的规则见下文。
```
```{warning} INFILE Path
:class: warning
在集群版中,如果`load_mode='cluster'`,`INFILE`路径的读取是由batchjob来完成的,如果是相对路径,就需要batchjob可以访问到的相对路径。
在生产环境中,batchjob的执行通常由yarn集群调度,难以确定具体的执行者。在测试环境中,如果也是多机部署,难以确定batchjob的具体执行者。
所以,请尽量使用绝对路径。单机测试中,本地文件用`file://`开头;生产环境中,推荐使用hdfs等文件系统。
```
## SQL语句模版
```sql
LOAD DATA INFILE 'file_path' INTO TABLE 'table_name' OPTIONS (key = value, ...);
```
## Hive 支持
OpenMLDB 支持从 Hive 导入数据,但需要额外的设置和功能限制,详情见 [Hive 支持](../../integration/offline_data_sources/hive.md)。
## Examples:
从`data.csv`文件读取数据到表`t1`在线存储中。并使用`,`作为列分隔符
```sql
set @@execute_mode='online';
LOAD DATA INFILE 'data.csv' INTO TABLE t1 OPTIONS(delimiter = ',', mode = 'append');
```
从`data.csv`文件读取数据到表`t1`中。并使用`,`作为列分隔符, 字符串"NA"将被替换为NULL。
```sql
LOAD DATA INFILE 'data.csv' INTO TABLE t1 OPTIONS(delimiter = ',', mode = 'append', null_value='NA');
```
将`data_path`软拷贝到表`t1`中,作为离线数据。
```sql
set @@execute_mode='offline';
LOAD DATA INFILE 'data_path' INTO TABLE t1 OPTIONS(deep_copy=false);
```
在离线模式下导入 Hive 数据仓库的表格:
```sql
set @@execute_mode='offline';
LOAD DATA INFILE 'hive://db1.t1' INTO TABLE t1;
```
## 在线导入规则
在线导入只允许`mode='append'`,无法`overwrite`或`error_if_exists`。
如果设置了 `insert_memory_usage_limit` session变量,服务端内存使用率超过设定的值就会返回失败。
## 离线导入规则
表的离线信息可通过`desc