1

我必须将输入文本文件 (text_file.txt) 复制到表 (table_a)。我还需要将输入文件的名称包含在表中。

我的代码是:

\set t_pwd `pwd`
\set input_file '\'':t_pwd'/text_file.txt\'' 

copy table_a
( column1
 ,column2
 ,column3
 ,FileName :input_file
)
from :input_file

最后一行不复制表中的输入文本文件名。如何将输入文本文件的名称复制到表中?(无需手动输入文件名)

4

2 回答 2

2

解决方案 1
这可能不是您工作的完美解决方案,但我认为可以完成工作:

您可以获取表名并将其存储在 TBL 变量中,然后将此变量添加到您将要加载到 Vertica 的 CSV 文件的每一行的末尾。
现在,根据您的 CSV 文件大小,这可能会耗费大量时间和 CPU。

export TBL=`ls -1 | grep *.txt` | sed -e 's/$/,'$TBL'/' -i $TBL

例子:

[dbadmin@bih001 ~]$ cat load_data1
1|2|3|4|5|6|7|8|9|10

[dbadmin@bih001 ~]$ export TBL=`ls -1 | grep load*` | sed -e 's/$/|'$TBL'/' -i $TBL

[dbadmin@bih001 ~]$ cat load_data1
1|2|3|4|5|6|7|8|9|10||load_data1

解决方案 2
您可以使用DEFAULT CONSTRAINT,请参见示例:
1. 使用DEFAULT CONSTRAINT创建表

[dbadmin@bih001 ~]$ vsql
Password:
Welcome to vsql, the Vertica Analytic Database interactive terminal.

Type:  \h or \? for help with vsql commands
       \g or terminate with semicolon to execute query
       \q to quit

dbadmin=> create table TBL (id int ,CSV_FILE_NAME varchar(200) default 'TBL');
CREATE TABLE
dbadmin=> \dt
              List of tables
 Schema | Name | Kind  |  Owner  | Comment
--------+------+-------+---------+---------
 public | TBL  | table | dbadmin |
(1 row)

请参阅默认约束它具有“TBL”默认值

dbadmin=> \d TBL
                                       List of Fields by Tables
 Schema | Table |    Column     |     Type     | Size | Default | Not Null | Primary Key | Foreign Key
--------+-------+---------------+--------------+------+---------+----------+-------------+-------------
 public | TBL   | id            | int          |    8 |         | f        | f           |
 public | TBL   | CSV_FILE_NAME | varchar(200) |  200 | 'TBL'   | f        | f           |
(2 rows)

2. 现在设置您的COPY变量
- 插入一些数据并将默认约束值更改为您的当前:input_file值。

dbadmin=> \set t_pwd `pwd`
dbadmin=> \set CSV_FILE `ls -1 | grep load*`
dbadmin=> \set input_file '\'':t_pwd'/':CSV_FILE'\''
dbadmin=>
dbadmin=>
dbadmin=> insert into TBL values(1);
 OUTPUT
--------
      1
(1 row)

dbadmin=> select * from TBL;
 id | CSV_FILE_NAME
----+---------------
  1 | TBL
(1 row)

dbadmin=> ALTER TABLE TBL  ALTER COLUMN CSV_FILE_NAME SET DEFAULT :input_file;
ALTER TABLE
dbadmin=> \dt TBL;
              List of tables
 Schema | Name | Kind  |  Owner  | Comment
--------+------+-------+---------+---------
 public | TBL  | table | dbadmin |
(1 row)

dbadmin=> \d TBL;
                                                 List of Fields by Tables
 Schema | Table |    Column     |     Type     | Size |          Default           | Not Null | Primary Key | Foreign Key
--------+-------+---------------+--------------+------+----------------------------+----------+-------------+-------------
 public | TBL   | id            | int          |    8 |                            | f        | f           |
 public | TBL   | CSV_FILE_NAME | varchar(200) |  200 | '/home/dbadmin/load_data1' | f        | f           |
(2 rows)

dbadmin=> insert into TBL values(2);
 OUTPUT
--------
      1
(1 row)

dbadmin=> select * from TBL;
 id |      CSV_FILE_NAME
----+--------------------------
  1 | TBL
  2 | /home/dbadmin/load_data1
(2 rows)

现在你可以在你的copy脚本中实现它了。
例子:

\set t_pwd `pwd`
\set CSV_FILE `ls -1 | grep load*`
\set input_file '\'':t_pwd'/':CSV_FILE'\''
ALTER TABLE TBL  ALTER COLUMN CSV_FILE_NAME SET DEFAULT :input_file;
copy TBL from :input_file DELIMITER '|' DIRECT;

解决方案 3

使用 LOAD_STREAMS表格
示例:
加载表格时给它一个stream name- 这样您就可以识别文件名/流名:

COPY mytable FROM myfile DELIMITER '|' DIRECT STREAM NAME 'My stream name';

*这是查询 load_streams 表的方法:*

=> SELECT stream_name, table_name, load_start, accepted_row_count, 
   rejected_row_count, read_bytes, unsorted_row_count, sorted_row_count,
   sort_complete_percent FROM load_streams;
-[ RECORD 1 ]----------+---------------------------
stream_name            | fact-13
table_name             | fact
load_start             | 2010-12-28 15:07:41.132053
accepted_row_count     | 900
rejected_row_count     | 100
read_bytes             | 11975
input_file_size_bytes  | 0
parse_complete_percent | 0
unsorted_row_count     | 3600
sorted_row_count       | 3600
sort_complete_percent  | 100

说得通 ?希望这有帮助!

于 2014-03-19T16:13:17.457 回答
1

如果您不需要纯粹从内部执行此操作vsql,则可能会作弊,并将逻辑导出到 Vertica 外部,例如 bash:

    FILE=text_file.txt
    (
      while read LINE; do
        echo "$LINE|$FILE"
      done < "$FILE"
    ) | vsql -c 'copy table_a (...) FROM STDIN'

这样,您基本上COPY FROM STDIN可以在每行到达 Vertica 之前将文件名添加到每一行。

于 2014-03-20T06:44:57.393 回答