概要
- Apache Hive の LOAD DATA で CSV ファイルをテーブルに読み込む例を示す
- 環境
- Apache Hive 3.1.2
- Apache Hadoop 3.2.0
- Java 8 (OpenJDK 8)
- Ubuntu 20.10 (Groovy Gorilla)
LOAD DATA 構文
LanguageManual DML - Apache Hive - Apache Software Foundation
LOAD DATA [LOCAL] INPATH 'filepath' [OVERWRITE] INTO TABLE tablename [PARTITION (partcol1=val1, partcol2=val2 ...)] [INPUTFORMAT 'inputformat' SERDE 'serde']
LOCAL
LOCAL を指定すると、ローカルのファイルシステムにあるファイルを Hadoop ファイルシステムにコピーし、コピーされたファイルは Hive が管理するテーブルデータ置き場に移動する。
LanguageManual DML - Apache Hive - Apache Software Foundation
the load command will try to copy all the files addressed by filepath to the target filesystem. The target file system is inferred by looking at the location attribute of the table. The copied data files will then be moved to the table.
LOCAL を指定しないと、Hadoop ファイルシステムにあるファイルを Hive が管理するテーブルデータ置き場に移動する (元の場所からファイルが消える)。
Hive will move the files addressed by filepath into the table (or partition)
OVERWRITE
OVERWRITE を指定すると、テーブルの中身がすべて削除される(パーティション指定の場合は指定したパーティションの中身がすべて削除される)。
LanguageManual DML - Apache Hive - Apache Software Foundation
If the OVERWRITE keyword is used then the contents of the target table (or partition) will be deleted and replaced by the files referred to by filepath; otherwise the files referred by filepath will be added to the table.
LOAD DATA で CSV ファイルを読み込む例
データベースとテーブルの準備
データベースを作成。
hive> create database foo_database;
OK
Time taken: 1.69 seconds
データベースを確認。
hive> show databases;
OK
default
foo_database
Time taken: 0.549 seconds, Fetched: 2 row(s)
テーブルを作成。
hive> create table foo_database.foo_table(
> id int,
> name string,
> updated_at timestamp)
> row format delimited
> fields terminated by ','
> lines terminated by '\n';
OK
Time taken: 1.777 seconds
テーブルを確認。
hive> show tables from foo_database;
OK
foo_table
Time taken: 0.171 seconds, Fetched: 1 row(s)
hive> show create table foo_database.foo_table;
OK
CREATE TABLE `foo_database.foo_table`(
`id` int,
`name` string,
`updated_at` timestamp)
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe'
WITH SERDEPROPERTIES (
'field.delim'=',',
'line.delim'='\n',
'serialization.format'=',')
STORED AS INPUTFORMAT
'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT
'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat'
LOCATION
'hdfs://localhost:9000/user/hive/warehouse/foo_database.db/foo_table'
TBLPROPERTIES (
'bucketing_version'='2',
'transient_lastDdlTime'='1618929431')
Time taken: 0.802 seconds, Fetched: 19 row(s)
CSV データファイルを用意
読み込む CSV ファイルをローカルのファイルシステムに3つ用意する。
data1.csv
100,Alice,2020-02-29 00:00:00.000000001
data2.csv
200,ボブ,1999-12-31 23:59:59
data3.csv
300,Carol,2021-04-20 00:00:00
LOAD DATA でローカルのファイルシステムにある CSV ファイルを読み込む
Hive からローカルにある data1.csv を読み込む。
LOAD DATA で LOCAL キーワードを指定するとローカルからファイルを読み込むようになる。
hive> LOAD DATA LOCAL INPATH 'file:/home/foo/data1.csv' INTO TABLE foo_database.foo_table;
Loading data to table foo_database.foo_table
OK
Time taken: 2.499 seconds
data1.csv のデータがテーブルに読み込まれたのを確認。
hive> select * from foo_database.foo_table;
OK
100 Alice 2020-02-29 00:00:00.000000001
Time taken: 5.529 seconds, Fetched: 1 row(s)
Hive からローカルにある data2.csv を読み込む。
hive> LOAD DATA LOCAL INPATH 'file:/home/foo/data2.csv' INTO TABLE foo_database.foo_table;
Loading data to table foo_database.foo_table
OK
Time taken: 0.64 seconds
data1.csv と data2.csv のデータが存在していることを確認。
hive> select * from foo_database.foo_table;
OK
100 Alice 2020-02-29 00:00:00.000000001
200 ボブ 1999-12-31 23:59:59
Time taken: 0.485 seconds, Fetched: 2 row(s)
Hadoop のファイルシステムを確認すると、読み込んだファイルが Hive 管理下のディレクトリに配置されているのがわかる。
$ hadoop fs -ls -R /user/hive/
drwxrwxr-x - foo supergroup 0 2021-04-20 23:36 /user/hive/warehouse
drwxr-xr-x - foo supergroup 0 2021-04-21 06:56 /user/hive/warehouse/foo_database.db
drwxr-xr-x - foo supergroup 0 2021-04-21 06:58 /user/hive/warehouse/foo_database.db/foo_table
-rw-r--r-- 1 foo supergroup 40 2021-04-21 06:57 /user/hive/warehouse/foo_database.db/foo_table/data1.csv
-rw-r--r-- 1 foo supergroup 31 2021-04-21 06:58 /user/hive/warehouse/foo_database.db/foo_table/data2.csv
Hive からローカルにある data3.csv を読み込む。
OVERWRITE を指定するとテーブルから既存のデータがすべて削除される。
hive> LOAD DATA LOCAL INPATH 'file:/home/foo/data3.csv' OVERWRITE INTO TABLE foo_database.foo_table;
Loading data to table foo_database.foo_table
OK
Time taken: 0.645 seconds
data1.csv と data2.csv のデータが削除され、data3.csv のデータがテーブルに読み込まれたのを確認。
hive> select * from foo_database.foo_table;
OK
300 Carol 2021-04-20 00:00:00
Time taken: 0.482 seconds, Fetched: 1 row(s)
データ削除
ここで一旦テーブルの中身を空にする。
hive> truncate table foo_database.foo_table;
OK
Time taken: 0.308 seconds
Hadoop ファイルシステム上に CSV データファイルを用意
hadoop fs コマンドで Hadoop ファイルシステム上に CSV ファイルを置くためのディレクトリを作成して、ローカルにある CSV ファイルをコピーする。
$ hadoop fs -mkdir /user/foo
$ hadoop fs -put data*.csv /user/foo
$ hadoop fs -ls /user/foo
Found 3 items
-rw-r--r-- 1 foo supergroup 40 2021-04-21 07:04 /user/foo/data1.csv
-rw-r--r-- 1 foo supergroup 31 2021-04-21 07:04 /user/foo/data2.csv
-rw-r--r-- 1 foo supergroup 30 2021-04-21 07:04 /user/foo/data3.csv
LOAD DATA で Hadoop ファイルシステムにある CSV ファイルを読み込む
Hive から Hadoop ファイルシステムにある data1.csv を読み込む。
hive> LOAD DATA INPATH '/user/foo/data1.csv' INTO TABLE foo_database.foo_table;
Loading data to table foo_database.foo_table
OK
Time taken: 0.622 seconds
data1.csv のデータがテーブルに読み込まれたのを確認。
hive> select * from foo_database.foo_table;
OK
100 Alice 2020-02-29 00:00:00.000000001
Time taken: 0.517 seconds, Fetched: 1 row(s)
Hive から Hadoop ファイルシステムにある data2.csv を読み込む。
hive> LOAD DATA INPATH '/user/foo/data2.csv' INTO TABLE foo_database.foo_table;
Loading data to table foo_database.foo_table
OK
Time taken: 0.552 seconds
data1.csv と data2.csv のデータが存在していることを確認。
hive> select * from foo_database.foo_table;
OK
100 Alice 2020-02-29 00:00:00.000000001
200 ボブ 1999-12-31 23:59:59
Time taken: 0.383 seconds, Fetched: 2 row(s)
Hadoop のファイルシステムを確認すると、読み込まれたファイル (data1.csv と data2.csv) が移動して消えているのがわかる。
$ hadoop fs -ls /user/foo
-rw-r--r-- 1 foo supergroup 30 2021-04-21 07:04 /user/foo/data3.csv
Hive から Hadoop ファイルシステムにある data3.csv を読み込む。
OVERWRITE を指定するとテーブルから既存のデータがすべて削除される。
hive> LOAD DATA INPATH '/user/foo/data3.csv' OVERWRITE INTO TABLE foo_database.foo_table;
Loading data to table foo_database.foo_table
OK
Time taken: 0.638 seconds
data1.csv と data2.csv のデータが削除され、data3.csv のデータがテーブルに読み込まれたのを確認。
hive> select * from foo_database.foo_table;
OK
300 Carol 2021-04-20 00:00:00
Time taken: 0.382 seconds, Fetched: 1 row(s)
Hadoop のファイルシステムを確認すると、読み込んだファイルが Hive 管理下のディレクトリに配置されているのがわかる。
$ hadoop fs -ls -R /user/hive/
drwxrwxr-x - foo supergroup 0 2021-04-20 23:36 /user/hive/warehouse
drwxr-xr-x - foo supergroup 0 2021-04-21 07:00 /user/hive/warehouse/foo_database.db
drwxr-xr-x - foo supergroup 0 2021-04-21 07:07 /user/hive/warehouse/foo_database.db/foo_table
-rw-r--r-- 1 foo supergroup 30 2021-04-21 07:04 /user/hive/warehouse/foo_database.db/foo_table/data3.csv
同じ名前のファイルを LOAD DATA した場合
同じファイル名で中身の違う CSV ファイルをローカルに用意。
data3.csv
400,Dave,2022-02-22 02:22:22
Hadoop ファイルシステムにコピー。
$ hadoop fs -put data3.csv /user/foo
Hive から Hadoop ファイルシステムにある data3.csv を読み込む。
hive> LOAD DATA INPATH '/user/foo/data3.csv' INTO TABLE foo_database.foo_table;
Loading data to table foo_database.foo_table
OK
Time taken: 1.91 seconds
同じファイル名のファイルを読み込んでも、以前のデータも残っていることが確認できる。
hive> select * from foo_database.foo_table;
OK
300 Carol 2021-04-20 00:00:00
400 Dave 2022-02-22 02:22:22
Time taken: 0.468 seconds, Fetched: 2 row(s)
Hive 管理下のディレクトリを確認すると、data3.csv が data3_copy_1.csv にリネームされて配置されているのがわかる。ファイル名が同じでも安全にデータを配置できている。
$ hadoop fs -ls -R /user/hive/
2021-04-21 10:13:45,733 WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin-java classes where applicable
drwxrwxr-x - foo supergroup 0 2021-04-20 23:36 /user/hive/warehouse
drwxr-xr-x - foo supergroup 0 2021-04-21 07:00 /user/hive/warehouse/foo_database.db
drwxr-xr-x - foo supergroup 0 2021-04-21 07:13 /user/hive/warehouse/foo_database.db/foo_table
-rw-r--r-- 1 foo supergroup 30 2021-04-21 07:04 /user/hive/warehouse/foo_database.db/foo_table/data3.csv
-rw-r--r-- 1 foo supergroup 29 2021-04-21 07:12 /user/hive/warehouse/foo_database.db/foo_table/data3_copy_1.csv