我一直在从MySQL导入一些数据到Postgres,计划应该很简单 - 手动重新创建具有等效数据类型的表,将输出方式作为CSV,传输数据,将其复制到Postgres中。完成。用于编码“UTF8”的无效字节序列:0xed 0xa0 0xbd
mysql -u whatever -p whatever -d the_database
SELECT * INTO OUTFILE '/tmp/the_table.csv' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' ESCAPED BY '\\' FROM the_table;
发送和进口的Postgres
psql -etcetc -d other_database
COPY the_table FROM '/csv/file/location/the_table.csv' WITH(FORMAT CSV, DELIMITER ',', QUOTE '"', ESCAPE '\', NULL '\N');
它已经太久了,我已经忘记了,“0000-00-00”是一件事...... 所以首先我不得不拿出解决怪异的数据类型的一些方法,最好是在MySQL的结束,所以写了这个剧本,20页左右的表我计划导入,以解决任何imcompatabilities并列出了相应的列
with a as (
select
'the_table'::text as tblname,
'public'::text as schname
), b as (
select array_to_string(array_agg(x.column_name), ',') as the_cols from (
select
case
when udt_name = 'timestamp'
then 'NULLIF('|| column_name::text || ',''0000-00-00 00:00:00'')'
when udt_name = 'date'
then 'NULLIF('|| column_name::text || ',''0000-00-00'')'
else column_name::text
end as column_name
from information_schema.columns, a
where table_schema = a.schname
and table_name = a.tblname
order by ordinal_position
) x
)
select 'SELECT '|| b.the_cols ||' INTO OUTFILE ''/tmp/'|| a.tblname ||'.csv'' FIELDS TERMINATED BY '','' OPTIONALLY ENCLOSED BY ''"'' ESCAPED BY ''\\'' FROM '|| a.tblname ||';' from a,b;
生成CSV,确定。跨越传输,确定 - 一旦结束了...
BEGIN;
ALTER TABLE the_table SET(autovacuum_enabled = false, toast.autovacuum_enabled = false);
COPY the_table FROM '/csv/file/location/the_table.csv' WITH(FORMAT CSV, DELIMITER ',', QUOTE '"', ESCAPE '\', NULL '\N'); -- '
ALTER TABLE the_table SET(autovacuum_enabled = true, toast.autovacuum_enabled = true);
COMMIT;
和它一切正常,直到我碰到这个消息传来:
ERROR: invalid byte sequence for encoding "UTF8": 0xed 0xa0 0xbd
CONTEXT: COPY new_table, line 12345678
第二台也遇到了同样的错误,但每隔一个成功导入。 现在在MySQL数据库中的所有列和表分别设置为utf8,包含的信息第一得罪桌子沿
CREATE TABLE whatever(
col1 int(11) NOT NULL AUTO_INCREMENT,
col2 date,
col3 int(11),
col4 int(11),
col5 int(11),
col6 int(11),
col7 varchar(64),
PRIMARY KEY(col1)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
的线,所以想必该数据应该是UTF ...对不对?确保有我编辑my.cnf中,以确保一切我能想到的,包括编码
[character sets]
default-character-set=utf8
default-character-set=utf8
character-set-server = utf8
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
我改变了我最初的“查询生成查询” case语句转换成列的缘故没有大的错误转换
case
when udt_name = 'timestamp'
then 'NULLIF('|| column_name::text || ',''0000-00-00 00:00:00'')'
when udt_name = 'date'
then 'NULLIF('|| column_name::text || ',''0000-00-00'')'
when udt_name = 'text'
then 'CONVERT('|| column_name::text || ' USING utf8)'
else column_name::text
end as column_name
仍然没有运气。谷歌搜索“0xed 0xa0 0xbd”之后,我仍然不明智,字符集并不是我的东西。 我甚至打开3 gig csv文件到它提到的那一行,看起来没有什么不合适的地方,用十六进制编辑器看,我看不到那些字节值(编辑:也许我没有看够硬)所以我开始用尽想法。我是否错过了一些非常简单的事情,而且令人担忧的是,其他一些表格可能是否已被更“默默”地破坏?
MySQL的版本是44年5月5日Ubuntu的14.04操作系统和Postgres的是9.4
从[这个答案中的表格](http://stackoverflow.com/a/6555104/1411457)看,0xed 0xa0 0xbd肯定是无效的UTF8。但是如果文件不包含那个字节序列,我看不出如何得到这个错误。 – harmic
该序列编码代码点'U + d83d'。这是一个结构上有效的序列,但它编码了一个无效的字符。 http://www.charbase.com/d83d-unicode-invalid-character。猜测,MySQL的验证比PostgreSQL更为松散,所以MySQL允许它和PostgreSQL拒绝它。 –
搜索“unicode eda0bd” - 它似乎有效,但未指定:http://dev.networkerror.org/utf8/?start=55335&end=55590&cols=4&show_uni_int=on&show_uni_hex=on&show_html_ent=on&show_raw_hex=on&show_raw_bin=on –