使用 COPY 将 csv 读入数据库,同时添加常量列
Use COPY to read a csv into database, while adding constant columns
我有一系列 CSV 文件,格式为:
"Alice","Bob","A",123.46,"4"
"Charlie","Dana","B",987.6543,"9"
...
我想制作这样的table:
id file_id mch c1 c2 c3 c4 c5
--- ------- ----- --------- ------ --- -------- ---
1 462 FALSE 'Alice' 'Bob' 'A' 123.46 '4'
2 462 FALSE 'Charlie' 'Dana' 'B' 987.6543 '9'
... 462 FALSE ... ... ... ... ...
... ... ... ... ... ... ... ...
其中
id
是主键,是任意的,应该是按照插入顺序自动生成的。它是这样指定的。
file_id
对于我要插入到此 table 的每个文件都是不变的,尽管文件之间会有所不同。在我尝试bulk-add文件之前就知道了。
mch
在插入时始终为假
c1
到 c5
是通用的列标题,类型是预先知道的。
目前我正在使用以下 SQL 命令来 bulk-insert 我的每个 CSV 文件:
COPY pos(c1,c2,c3,c4,c5)
FROM 'C:/Users/.../filename.csv'
WITH (FORMAT CSV, HEADER FALSE, ENCODING 'UTF8')
用于填充主键 ID。这会生成一个没有 file_id
或 mch
列的 table。
但我无法弄清楚如何在同一条语句中正确填充其他两列(file_id
和 mch
),而不执行整个其他 UPDATE
语句。
假设这个 table 定义:
CREATE TABLE pos (
id serial PRIMARY KEY
, file_id int
, mch bool
, c1 text
, c2 text
, c3 text
, c4 numeric
, c5 text
);
Table columns not specified in the COPY FROM
column list will receive their default values.
您已经看到 id
的效果,其中分配了默认值。其余要处理的列:mch
和 file_id
:
mch
is always false, at time of insertion
永久地做到这一点:
ALTER TABLE pos ALTER mc SET DEFAULT false;
必要权限:您必须拥有 table 或成为超级用户才能使用 ALTER TABLE
。
file_id
is constant per file that I want to insert to this table, though varies between files. It is known before I try to bulk-add the file.
在运行宁COPY
之前设置列默认值。如果您不希望其他插入具有相同的默认值,则可以在事务内执行此操作。 (DDL 命令在 Postgres 中是完全事务性的。)但这会为事务的其余部分锁定 table (ACCESS EXCLUSIVE
lock)。
或者您在 COPY
之前 运行 一个单独的命令(在它自己的事务中)。那么默认值可能对并发事务有效。但是您只需要对 table.
进行非常简短的锁定
-- BEGIN; -- optional transaction wrapper
ALTER TABLE pos ALTER file_id SET DEFAULT 462;
COPY pos(c1,c2,c3,c4,c5)
FROM 'C:/Users/.../filename.csv'
WITH (FORMAT CSV, HEADER FALSE, ENCODING 'UTF8'); -- unchanged!
-- ALTER TABLE pos ALTER file_id DROP DEFAULT; -- optional
-- COMMIT; -- if you BEGIN; also COMMIT;
您可能想要也可能不想在 COPY
之后重置 file_id
的列默认值。如果您要 运行 下一个 COPY
之后立即使用新的默认值,您可能只需设置新的默认值 ...
或者您可能想要记录旧的列默认值并重置它。参见:
- Get the default values of table columns in Postgres?
我有一系列 CSV 文件,格式为:
"Alice","Bob","A",123.46,"4"
"Charlie","Dana","B",987.6543,"9"
...
我想制作这样的table:
id file_id mch c1 c2 c3 c4 c5
--- ------- ----- --------- ------ --- -------- ---
1 462 FALSE 'Alice' 'Bob' 'A' 123.46 '4'
2 462 FALSE 'Charlie' 'Dana' 'B' 987.6543 '9'
... 462 FALSE ... ... ... ... ...
... ... ... ... ... ... ... ...
其中
id
是主键,是任意的,应该是按照插入顺序自动生成的。它是这样指定的。file_id
对于我要插入到此 table 的每个文件都是不变的,尽管文件之间会有所不同。在我尝试bulk-add文件之前就知道了。mch
在插入时始终为假c1
到c5
是通用的列标题,类型是预先知道的。
目前我正在使用以下 SQL 命令来 bulk-insert 我的每个 CSV 文件:
COPY pos(c1,c2,c3,c4,c5)
FROM 'C:/Users/.../filename.csv'
WITH (FORMAT CSV, HEADER FALSE, ENCODING 'UTF8')
用于填充主键 ID。这会生成一个没有 file_id
或 mch
列的 table。
但我无法弄清楚如何在同一条语句中正确填充其他两列(file_id
和 mch
),而不执行整个其他 UPDATE
语句。
假设这个 table 定义:
CREATE TABLE pos (
id serial PRIMARY KEY
, file_id int
, mch bool
, c1 text
, c2 text
, c3 text
, c4 numeric
, c5 text
);
Table columns not specified in the
COPY FROM
column list will receive their default values.
您已经看到 id
的效果,其中分配了默认值。其余要处理的列:mch
和 file_id
:
mch
is always false, at time of insertion
永久地做到这一点:
ALTER TABLE pos ALTER mc SET DEFAULT false;
必要权限:您必须拥有 table 或成为超级用户才能使用 ALTER TABLE
。
file_id
is constant per file that I want to insert to this table, though varies between files. It is known before I try to bulk-add the file.
在运行宁COPY
之前设置列默认值。如果您不希望其他插入具有相同的默认值,则可以在事务内执行此操作。 (DDL 命令在 Postgres 中是完全事务性的。)但这会为事务的其余部分锁定 table (ACCESS EXCLUSIVE
lock)。
或者您在 COPY
之前 运行 一个单独的命令(在它自己的事务中)。那么默认值可能对并发事务有效。但是您只需要对 table.
-- BEGIN; -- optional transaction wrapper
ALTER TABLE pos ALTER file_id SET DEFAULT 462;
COPY pos(c1,c2,c3,c4,c5)
FROM 'C:/Users/.../filename.csv'
WITH (FORMAT CSV, HEADER FALSE, ENCODING 'UTF8'); -- unchanged!
-- ALTER TABLE pos ALTER file_id DROP DEFAULT; -- optional
-- COMMIT; -- if you BEGIN; also COMMIT;
您可能想要也可能不想在 COPY
之后重置 file_id
的列默认值。如果您要 运行 下一个 COPY
之后立即使用新的默认值,您可能只需设置新的默认值 ...
或者您可能想要记录旧的列默认值并重置它。参见:
- Get the default values of table columns in Postgres?