首页 > 解决方案 > 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 ../../

标签: bashsqlite

解决方案


在这种情况下,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_DeliveredTEXT,因为这就是当时的情况:它仅作为“日期”插入companydata_client.


推荐阅读