我已经看了很多关于这个主题的类似问题。。但似乎都不适用。以下是详细信息:
我有一张有8列的桌子。
create table test (
node_name varchar(200),
parent varchar(200),
actv int(11),
fid int(11),
cb varchar(100),
co datetime,
ub varchar(100),
uo datetime
);
桌子上有一个触发器:
CREATE TRIGGER before_insert_test
BEFORE INSERT ON test
FOR EACH ROW SET NEW.co = now(), NEW.uo = now(), NEW.cb = user(), NEW.ub = user()
我有一个csv文件要加载到此表中。它只有两列。前几行:
node_name,parent
West,
East,
BBB: someone,West
Quebec,East
Ontario,East
Manitoba,West
British Columbia,West
Atlantic,East
Alberta,West
我在mySQL 5.6环境中设置了这一切。使用python和SQLAlchemy,我毫无问题地运行了文件的加载。。它为前2条记录中的第二个字段加载所有具有空字符串的记录。一切如预期。
我有一个mysql8环境,运行完全相同的例程。所有相同的语句等。它以"Row 1 not contained data for All columns"错误而失败。
使用以下方式进行连接:
engine = create_engine(
connection_string,
pool_size=6, max_overflow=10, encoding='latin1', isolation_level='AUTOCOMMIT',
connect_args={"local_infile": 1}
)
db_connection = engine.connect()
我在sql变量中放置的命令是:
LOAD DATA INFILE 'test.csv'
INTO TABLE test
FIELDS TERMINATED BY ',' ENCLOSED BY '"' IGNORE 1 LINES SET fid = 526, actv = 1;
并使用执行
db_connection.execute(sql)
所以。。我基本上加载文件的前两列。。我在load语句中设置接下来的2列,最后4列由触发器处理。
我重复一遍-这在mysql 5环境中运行良好,但在mysql 8环境中运行不好。
我在两个数据库环境中都检查了mysql字符集变量,它们是等效的(只是为了防止5.6和8之间的默认字符集更改产生影响(。
我要说的是,mySQL 5 db在ubuntu 18.04.5上运行,而mySQL 8在ubuntu 20.02.2上运行——会有什么吗??
我已经尝试过各种篡改LOAD DATA语句的方法。。我试着为文件中的前两条记录填写数据,以防出现这种情况。我试着在LOAD语句中使用不同的行终止符。。我不知道下一件要调查的事情。。谢谢你的指点。。
MySQL将假设CSV中的每一行都映射到表中的一列,除非您另有说明。
给查询一个列列表:
LOAD DATA INFILE 'test.csv'
INTO TABLE test
FIELDS TERMINATED BY ','
ENCLOSED BY '"'
IGNORE 1 LINES
(node_name, parent)
SET fid = 526, actv = 1;
除了切线垂直的答案外,还有其他选项:
-
根据添加IGNORE关键字:https://dev.mysql.com/doc/refman/8.0/en/sql-mode.html#ignore-对执行的影响它应该位于LOAD DATA语句中的INTO之前,根据https://dev.mysql.com/doc/refman/8.0/en/load-data.html.
-
或者,将sql_mode更改为不那么严格也可以。
由于严格的sql_mode,LOAD DATA不够聪明,无法意识到TRIGGERS正在处理几个列。。如果他们能把它改进得那么聪明就好了。。但是唉。