我有一个Bash ETL进程,它接受一个CSV文件,修复其格式(如果需要)并将内容加载到MariaDB数据库中。我发现保存到数据库的记录少于文件中的记录,我试图理解原因。作为该过程的一部分,我在-vv
命令中添加mysql
以查看它正在做什么,输出正在抛弃我。
我导入的文件有 366 行(包括标题)。
我的命令:
out=$(mysql -h ${host} \
-vv \
-P ${port} \
-u ${user} \
-p"${password}" \
--local-infile \
my_table < ${scriptDir}/${target}.sql 2>&1)
相关回复看起来像这样(我添加了换行符):
LOAD DATA LOCAL INFILE '/tmp/mydata.csv'
REPLACE INTO TABLE my_table CHARACTER SET utf8
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
SET updated_at = NOW()
--------------
Query OK, 410 rows affected, 1460 warnings
Records: 365 Deleted: 45 Skipped: 0 Warnings: 1460 Bye
这是第一次导入表格。知道什么可能导致45条记录被此声明删除?
任何想法都会受到赞赏。
更新
根据要求,这是表格定义:
CREATE TABLE `my_table` (
`First Name` varchar(255) DEFAULT NULL,
`Last Name` varchar(255) DEFAULT NULL,
`Company` varchar(255) DEFAULT NULL,
`Email` varchar(255) DEFAULT NULL,
`Campaign Name` varchar(255) DEFAULT NULL,
`Event Date` date DEFAULT NULL,
`Live Views Duration` varchar(255) DEFAULT NULL,
`On Demand Views Duration` varchar(255) DEFAULT NULL,
`Job Title` varchar(255) DEFAULT NULL,
`Reg Date` varchar(255) DEFAULT NULL,
`Affiliate Data` varchar(255) DEFAULT NULL,
`Phone 1` varchar(255) DEFAULT NULL,
`City` varchar(255) DEFAULT NULL,
`State` varchar(255) DEFAULT NULL,
`Postal Code` varchar(255) DEFAULT NULL,
`Country` varchar(255) DEFAULT NULL,
`Industry` varchar(255) DEFAULT NULL,
`id` int(11) NOT NULL AUTO_INCREMENT,
`updated_at` datetime DEFAULT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `uix_conversion` (`Email`,`Campaign Name`,`Event Date`),
KEY `ix_campaign_name` (`Campaign Name`)
) ENGINE=InnoDB AUTO_INCREMENT=512 DEFAULT CHARSET=utf8;
更新
经过一段时间后,我删除了唯一索引,没有任何变化。我还将REPLACE
查询更改为IGNORE
查询,现在跳过而不是删除记录。净影响相同。此外,在多次测试同一文件时,似乎缺少的记录并不总是相同缺失的记录。不知道这里发生了什么......
答案 0 :(得分:1)
documentation非常清楚地说明了这一点:
REPLACE
和IGNORE
关键字控制处理与唯一键值上的现有行重复的输入行:
- 如果指定
REPLACE
,则输入行将替换现有行。换句话说,主键或唯一索引的值与现有行的值相同。
如果在运行LOAD DATA INFILE
命令时表格为空,则表示从.csv
文件导入的某些行在导入{{1}的列中包含重复值表格或表格中有PK
的列。
如果要导入的行包含的值与UNIQUE INDEX
或PK
列中已导入的行的值重复,则UNIQUE INDEX
关键字会生成已导入的行要删除以便为新行腾出空间(不违反REPLACE
或PRIMARY
约束)。
在您发布表格定义后更新了答案:在UNIQUE
列中搜索重复项,并在id
中搜索具有相同值集的行,输入Email
文件的Campaign Name
,Event Date
列。
更新#2 (在OP评论之后):
如果.csv
文件在.csv
列中包含非空值,则导入的这些值和id
列的AUTO_INCREMENT
属性不会计数。
您可以通过指定要使用id
文件中的数据设置的列列表来跳过导入id
列(让AUTO_INCREMENT
完成其工作):< / p>
.csv
列表中未显示但未在LOAD DATA LOCAL INFILE '/tmp/mydata.csv'
REPLACE INTO TABLE my_table CHARACTER SET utf8
FIELDS TERMINATED BY ','
OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
IGNORE 1 LINES
(`First Name`, `Last Name`, # put the rest of the column names here
# in the same order they are in the .csv file
# put a variable (like @a) to skip a column
# or to use the value in an expression in the SET clause
`Country`, `Industry`) # but do not put `id`
SET updated_at = NOW()
子句中设置的列将使用SET
值进行设置(这是为{{1}调用DEFAULT
的位置}})。