bash - sqlite3 无法仅从 1 个 tsv 文件导入数据
问题描述
问题
我正在创建一个脚本,将大量 tsv 文件混合在一起,然后将数据导入到我的 sqlite3 表中。但是,我注意到我的一个文件似乎没有像所有其他文件一样随我的脚本一起导入。当我手动运行它时,它似乎也没有导入。
由于数据能够毫无问题地进入临时表,我认为问题可能出在日期列上,但即使将数据中的数据修改为 YMD 格式,由于某种原因它仍然无法导入。
有人可以确认示例数据似乎有什么问题,因为所有其他 tsv 文件似乎都可以毫无问题地导入吗?
样本.tsv
company1 account1 platform1 05/05/2020 28823 client1 191361
company2 account2 platform2 05/05/2020 47188 cleint2 16597
company3 account3 platform3 05/06/2020 28823 client1 191903
company4 account4 platform4 05/06/2020 47188 cleint2 15407
company5 account5 platform5 05/07/2020 28823 client1 196450
company6 account6 platform6 05/07/2020 47188 cleint2 14678
company7 account7 platform7 05/08/2020 28823 client1 191809
company8 account8 platform8 05/08/2020 47188 cleint2 14489
company9 account9 platform9 05/09/2020 28823 client1 195405
脚本.sh
#!/bin/bash
set -eu
cd final/client/
for f in $(find -mindepth 1 -maxdepth 1 -type f -name "*.tsv" -printf "%f\n"); do
sqlite3 -batch ~/SQL/.databases/database.db <<EOF
CREATE TABLE IF NOT EXISTS companydata_client(
Company TEXT NOT NULL,
Account TEXT NOT NULL,
Platform TEXT NOT NULL,
Impression_Date_Delivered DATE NOT NULL,
Client_ID TEXT NOT NULL,
Client TEXT NOT NULL,
Impressions INTEGER,
UNIQUE(Company,Account,Platform,Impression_Date_Delivered,Client_ID, Client,Impressions)
);
CREATE TEMPORARY TABLE wand(
Company TEXT NOT NULL,
Account TEXT NOT NULL,
Platform TEXT NOT NULL,
Impression_Date_Delivered DATE NOT NULL,
Client_ID TEXT NOT NULL,
Client TEXT NOT NULL,
Impressions INTEGER
);
.mode tabs
.separator \t
.import $f wand
INSERT OR IGNORE INTO companydata_client (Company,Account,Platform,Impression_Date_Delivered,Client_ID,Client,Impressions)
SELECT
CAST (Company AS TEXT),
CAST (Account AS TEXT),
CAST (Platform AS TEXT),
strftime('%d-%m-%Y',Impression_Date_Delivered),
CAST (Client_ID AS Text),
CAST (Client AS TEXT),
CAST (Impressions AS Integer)
FROM wand;
EOF
done
cd ../../
解决方案
在这种情况下,Sqlite 似乎有点不幸,因为它strftime
是将日期转换为字符串,但似乎没有等效strptime
的,可以将字符串转换为日期。(事实上,所有日期在 Sqlite 中都是有效的字符串。我认为它们只是被解析和解释为相关功能的日期。)
按照这个问题的答案,你最终会得到这样的结果:
INSERT OR IGNORE INTO companydata_client (Company,Account,Platform,Impression_Date_Delivered,Client\
_ID,Client,Impressions)
SELECT
CAST (Company AS TEXT),
CAST (Account AS TEXT),
CAST (Platform AS TEXT),
substr(Impression_Date_Delivered, 7) || '-' ||
substr(Impression_Date_Delivered, 4, 2) || '-' ||
substr(Impression_Date_Delivered, 1, 2),
CAST (Client_ID AS Text),
CAST (Client AS TEXT),
CAST (Impressions AS Integer)
FROM wand;
EOF
不是最易读的行,但这似乎是要走的路(直到其他人提出更好的答案)。格式化应该产生一个 Sqlite 可以解释为日期的字符串。
旁白:我将 的类型更改wand.Impression_Date_Delivered
为TEXT
,因为这就是当时的情况:它仅作为“日期”插入companydata_client
.