ลำดับไบต์ไม่ถูกต้องสำหรับการเข้ารหัส“ UTF8”


125

ฉันกำลังพยายามนำเข้าข้อมูลบางส่วนไปยังฐานข้อมูลของฉัน ฉันจึงสร้างตารางชั่วคราว

create temporary table tmp(pc varchar(10), lat decimal(18,12), lon decimal(18,12), city varchar(100), prov varchar(2));

และตอนนี้ฉันพยายามที่จะนำเข้าข้อมูล ,

 copy tmp from '/home/mark/Desktop/Canada.csv' delimiter ',' csv

แต่แล้วฉันก็ได้รับข้อผิดพลาด

ERROR:  invalid byte sequence for encoding "UTF8": 0xc92c

ฉันจะแก้ไขได้อย่างไร ฉันจำเป็นต้องเปลี่ยนการเข้ารหัสของฐานข้อมูลทั้งหมดของฉันหรือไม่ (ถ้าเป็นเช่นนั้นจะทำอย่างไร) หรือฉันจะเปลี่ยนแค่การเข้ารหัสtmpตารางของฉันได้หรือไม่ หรือฉันควรพยายามเปลี่ยนการเข้ารหัสของไฟล์?


เปลี่ยนตัวเลือกการเข้ารหัสในการนำเข้า ฉันตั้งค่าของฉันเป็น "Windows-1251" และใช้งานได้โดยไม่มีการร้องเรียน
Brian D

1
ขอบคุณ @BrianD ฉันประสบปัญหานี้เช่นกันและสิ่งนี้ใช้ได้ผลสำหรับฉัน
gouravkr

คำตอบ:


110

หากคุณต้องการจัดเก็บข้อมูล UTF8 ในฐานข้อมูลของคุณคุณต้องมีฐานข้อมูลที่ยอมรับ UTF8 คุณสามารถตรวจสอบการเข้ารหัสของฐานข้อมูลของคุณใน pgAdmin เพียงคลิกขวาที่ฐานข้อมูลและเลือก "Properties"

แต่ข้อผิดพลาดนั้นดูเหมือนจะบอกคุณว่ามีข้อมูล UTF8 ที่ไม่ถูกต้องในไฟล์ต้นฉบับของคุณ นั่นหมายความว่าcopyยูทิลิตี้ตรวจพบหรือเดาว่าคุณกำลังป้อนไฟล์ UTF8

หากคุณใช้ Unix บางรุ่นคุณสามารถตรวจสอบการเข้ารหัส (มากหรือน้อย) ด้วยfileยูทิลิตี้

$ file yourfilename
yourfilename: UTF-8 Unicode English text

(ฉันคิดว่าจะใช้ได้กับ Mac ในเทอร์มินัลด้วย) ไม่แน่ใจว่าจะทำอย่างไรใน Windows

หากคุณใช้ยูทิลิตี้เดียวกันกับไฟล์ที่มาจากระบบ Windows (นั่นคือไฟล์ที่ไม่ได้เข้ารหัส UTF8) มันอาจจะแสดงสิ่งนี้:

$ file yourfilename
yourfilename: ASCII text, with CRLF line terminators

หากสิ่งต่างๆยังคงแปลกอยู่คุณอาจลองแปลงข้อมูลอินพุตของคุณเป็นการเข้ารหัสที่รู้จักเพื่อเปลี่ยนการเข้ารหัสของไคลเอ็นต์ของคุณหรือทั้งสองอย่าง (เรากำลังขยายขีด จำกัด ของความรู้ของฉันเกี่ยวกับการเข้ารหัส)

คุณสามารถใช้iconvยูทิลิตี้เพื่อเปลี่ยนการเข้ารหัสข้อมูลอินพุต

iconv -f original_charset -t utf-8 originalfile > newfile

คุณสามารถเปลี่ยน psql (ลูกค้า) การเข้ารหัสตามคำแนะนำบนตัวอักษรชุดสนับสนุน ในหน้านั้นค้นหาวลี "เพื่อเปิดใช้งานการแปลงชุดอักขระอัตโนมัติ"


3
บอกว่าไฟล์เป็น ASCII แต่มีอักขระเน้นเสียงดังนั้นต้องผิดหรือไม่?
mpen

2
จะยอมรับคำตอบนี้ แต่ฉันคิดว่าปัญหาเกิดจากข้อมูล (อัพเดต Q)
mpen

1
ฉันพบว่าสิ่งนี้มีประโยชน์ขอบคุณ อย่างไรก็ตามมันทำงานบนเทอร์มินัล OS X ด้วยเช่นกัน
Raul Rene

1
สิ่งนี้ใช้ได้ผลสำหรับฉัน แต่ในทางที่แตกต่างกันเล็กน้อย คำสั่ง "iconv" ระเบิดในไฟล์ของฉันจริง ๆ แต่มันทำได้ถูกต้องในจุดที่เป็นปัญหา - อักขระ "-" แปลก ๆ อย่างไรก็ตามฉันลบมันออกและไฟล์ของฉันก็สามารถโหลดลงใน postgres ได้ ขอบคุณสำหรับทิป!
trip0d199

1
เพียงเพื่อช่วยเหลือผู้อื่นและเครื่องมือค้นหา: สิ่งนี้ใช้ได้กับการแปลงการส่งออก Stripe CSV ที่มีอักขระที่อ่านไม่ได้กลับไปเป็น UTF-8: "iconv -f ISO-8859-15 -t utf-8 customers.csv> customers-utf8.csv`
sscarduzio

57
psql=# copy tmp from '/path/to/file.csv' with delimiter ',' csv header encoding 'windows-1251';

การเพิ่มencodingตัวเลือกใช้งานได้ในกรณีของฉัน


1
จะเสร็จสมบูรณ์โดยไม่มีข้อผิดพลาดอาจให้ผลลัพธ์ที่เป็นประโยชน์หรือไม่ก็ได้ คุณจำเป็นต้องทราบการเข้ารหัสข้อมูลที่ตั้งใจไว้
Jasen

1
ในสถานการณ์ของฉันแบบสอบถามข้างต้นทำงานอย่างไร ฉันมีไฟล์ csv ที่เข้ารหัสด้วย UTF8 และ DB ที่เข้ารหัสด้วย UTF8
Ajay Takur

14

เห็นได้ชัดว่าฉันสามารถตั้งค่าการเข้ารหัสได้ทันที

 set client_encoding to 'latin1'

จากนั้นเรียกใช้แบบสอบถามอีกครั้ง ไม่แน่ใจว่าควรใช้การเข้ารหัสแบบใด


latin1ทำให้อักขระชัดเจน แต่อักขระที่เน้นเสียงส่วนใหญ่เป็นตัวพิมพ์ใหญ่ในที่ที่ไม่ควรเป็น ฉันคิดว่านี่เป็นเพราะการเข้ารหัสที่ไม่ดี แต่ฉันคิดว่ามันเป็นข้อมูลที่ไม่ดีจริงๆ ฉันลงเอยด้วยการรักษาการเข้ารหัส latin1 แต่ประมวลผลข้อมูลล่วงหน้าและแก้ไขปัญหาการใส่ปลอก


ที่น่าสนใจคือฉันได้รับข้อผิดพลาดในคำสั่ง SELECT! สิ่งนี้แก้ไขได้เนื่องจากเป็นไคลเอนต์ psql ของฉันที่ให้ข้อผิดพลาดไม่ใช่ฐานข้อมูลเอง (ซึ่งจะปฏิเสธข้อมูลตั้งแต่แรกโดยมีการห้ามการเข้ารหัส)
สัญลักษณ์แทน

14

หากคุณพอใจกับการทิ้งอักขระที่ไม่สามารถแปลงกลับได้คุณสามารถใช้-cแฟล็ก

iconv -c -t utf8 filename.csv > filename.utf8.csv

จากนั้นคัดลอกลงในตารางของคุณ


บน Mac iconv -c -t UTF-8 filename.csv > filename.utf8.csvสำหรับฉัน
Michael

8

ข้อผิดพลาดนี้หมายความว่าการเข้ารหัสระเบียนในไฟล์แตกต่างกันเมื่อเทียบกับการเชื่อมต่อ ในกรณีนี้ iconv อาจส่งคืนข้อผิดพลาดบางครั้งแม้จะตั้งค่าสถานะ // IGNORE:

iconv -f ASCII -t utf-8 // IGNORE <b.txt> /a.txt

iconv: ลำดับการป้อนข้อมูลที่ไม่ถูกต้องที่ตำแหน่ง (ตัวเลขบางตัว)

เคล็ดลับคือการค้นหาอักขระที่ไม่ถูกต้องและแทนที่ หากต้องการทำบน Linux ให้ใช้โปรแกรมแก้ไข "vim":

กลุ่ม (ไฟล์ข้อความของคุณ) กด ​​"ESC": ปุ่มและพิมพ์ ": goto (หมายเลขที่ส่งคืนโดย iconv)"

หากต้องการค้นหาอักขระที่ไม่ใช่ ASCII คุณสามารถใช้คำสั่งต่อไปนี้:

grep --color = 'อัตโนมัติ' -P "[\ x80- \ xFF]"

หากคุณลบอักขระที่ไม่ถูกต้องโปรดตรวจสอบว่าคุณจำเป็นต้องแปลงไฟล์จริงๆหรือไม่: อาจเป็นปัญหาได้รับการแก้ไขแล้ว


iconv -c -f utf8 -t utf8//IGNORE < dirty.txt > clean.txt
Jasen

5

ทำตามขั้นตอนด้านล่างเพื่อแก้ไขปัญหานี้ใน pgadmin:

  1. SET client_encoding = 'ISO_8859_5';

  2. COPY tablename(column names) FROM 'D:/DB_BAK/csvfilename.csv' WITH DELIMITER ',' CSV ;


4

ขึ้นอยู่กับประเภทของเครื่อง / การเข้ารหัสที่สร้างไฟล์นำเข้าของคุณ

หากคุณได้รับมาจาก Windows เวอร์ชันภาษาอังกฤษหรือยุโรปตะวันตกทางออกที่ดีที่สุดของคุณอาจตั้งค่าเป็น "WIN1252" หากคุณได้รับมาจากแหล่งอื่นโปรดดูรายการการเข้ารหัสอักขระที่นี่:

http://www.postgresql.org/docs/8.3/static/multibyte.html

หากคุณได้รับมาจาก Mac คุณอาจต้องเรียกใช้ผ่านยูทิลิตี้ "iconv" ก่อนเพื่อแปลงจาก MacRoman เป็น UTF-8


4

ฉันก็ประสบปัญหาเดียวกัน และสิ่งที่แก้ปัญหาของฉันคือ:

ใน excel คลิกที่บันทึกเป็น จากการบันทึกเป็นชนิดให้เลือก.csv คลิกที่เครื่องมือ จากนั้นเลือกตัวเลือกเว็บจากรายการแบบเลื่อนลง ภายใต้การเข้ารหัสแท็บบันทึกเอกสารเป็นUnicode (UTF-8) คลิกตกลง บันทึกไฟล์ เสร็จ!


3

ฉันมีปัญหาเดียวกันและพบวิธีแก้ปัญหาที่ดีที่นี่: http://blog.e-shell.org/134

สิ่งนี้เกิดจากการเข้ารหัสฐานข้อมูลของคุณไม่ตรงกันแน่นอนเนื่องจากฐานข้อมูลที่คุณได้รับการถ่ายโอนข้อมูล SQL ถูกเข้ารหัสเป็น SQL_ASCII ในขณะที่ฐานข้อมูลใหม่ถูกเข้ารหัสเป็น UTF8 .. Recode เป็นเครื่องมือขนาดเล็กจากโปรเจ็กต์ GNU ที่ให้คุณเปลี่ยนการเข้ารหัสของไฟล์ที่กำหนดได้ทันที

ดังนั้นฉันจึงเพิ่งบันทึกไฟล์ดัมพ์ก่อนที่จะเล่นมัน:

postgres> gunzip -c /var/backups/pgall_b1.zip | recode iso-8859-1..u8 | psql test

ในระบบ Debian หรือ Ubuntu สามารถติดตั้ง Recode ผ่านแพ็คเกจได้


2

คุณสามารถแทนที่อักขระแบ็กสแลชด้วยตัวอย่างเช่นอักขระไปป์ด้วย sed

sed -i -- 's/\\/|/g' filename.txt

2
copy tablename from 'filepath\filename' DELIMITERS '=' ENCODING 'WIN1252';

คุณสามารถลองใช้วิธีนี้เพื่อจัดการกับการเข้ารหัส UTF8


2

ตัวอย่างสั้น ๆ เพื่อแก้ไขปัญหานี้ใน PHP-

$val = "E'\377'";
iconv(mb_detect_encoding($val, mb_detect_order(), true), "UTF-8", $val);

รายละเอียดข้อผิดพลาด: เนื่องจากฐานข้อมูล POSTGRES ไม่จัดการอักขระอื่นที่ไม่ใช่ UTF-8 เมื่อเราพยายามส่งอินพุตที่กำหนดข้างต้นไปยังคอลัมน์จึงทำให้เกิดข้อผิดพลาด "ลำดับไบต์ที่ไม่ถูกต้องสำหรับการเข้ารหัส" UTF8 ": 0xab"

ดังนั้นเพียงแค่แปลงค่านั้นเป็น UTF-8 ก่อนที่จะแทรกในฐานข้อมูล POSTGRES


2

ฉันมีปัญหาเดียวกัน: ไฟล์ของฉันไม่ได้เข้ารหัสเป็น UTF-8 ฉันได้แก้ไขโดยการเปิดไฟล์ด้วย notepad ++ และเปลี่ยนการเข้ารหัสของไฟล์

ไปที่ "การเข้ารหัส" และเลือก "แปลงเป็น UTF-8" บันทึกการเปลี่ยนแปลงเพียงเท่านี้!


1

ข้อผิดพลาดนี้อาจเกิดขึ้นหากข้อมูลอินพุตมีอักขระหลีกเอง โดยค่าเริ่มต้นอักขระหลีกคือสัญลักษณ์ "\" ดังนั้นหากข้อความที่คุณป้อนมีอักขระ "\" ให้ลองเปลี่ยนค่าเริ่มต้นโดยใช้ตัวเลือก ESCAPE


1

สำหรับ python คุณต้องใช้

คลาส pg8000.types Bytea (str) Bytea เป็นคลาสที่ได้รับ str ที่แมปกับอาร์เรย์ไบต์ PostgreSQL

หรือ

Pg8000.Binary (ค่า) สร้างวัตถุที่เก็บข้อมูลไบนารี


1

ฉันพบปัญหานี้ใน Windows ในขณะที่ทำงานเฉพาะกับ psql (ไม่มีเครื่องมือกราฟิก) ในการแก้ไขปัญหานี้ให้เปลี่ยนการเข้ารหัสเริ่มต้นของ psql (ไคลเอนต์) อย่างถาวรเพื่อให้ตรงกับการเข้ารหัสเริ่มต้นของเซิร์ฟเวอร์ PostgreSQL เรียกใช้คำสั่งต่อไปนี้ใน CMD หรือ Powershell:

setx PGCLIENTENCODING UTF8

ปิดและเปิดพรอมต์คำสั่ง / Powershell อีกครั้งเพื่อให้การเปลี่ยนแปลงมีผล

เปลี่ยนการเข้ารหัสของไฟล์สำรองจาก Unicode เป็น UTF8 โดยเปิดด้วย Notepad แล้วไปที่ File -> Save As เปลี่ยนดรอปดาวน์การเข้ารหัสจาก Unicode เป็น UTF8 (และเปลี่ยนประเภท Save as จาก Text Documents (.txt) เป็น All Files เพื่อหลีกเลี่ยงการเพิ่มนามสกุล. txt ในชื่อไฟล์สำรองของคุณ) ตอนนี้คุณควรจะกู้คืนข้อมูลสำรองได้แล้ว


0

นอกจากนี้ยังเป็นไปได้อย่างมากที่เกิดข้อผิดพลาดที่ช่องถูกเข้ารหัส ตรวจสอบว่าคุณกำลังดูตารางที่ถูกต้องในบางกรณีผู้ดูแลระบบจะสร้างมุมมองที่ไม่ได้เข้ารหัสซึ่งคุณสามารถใช้แทนได้ เมื่อเร็ว ๆ นี้ฉันพบปัญหาที่คล้ายกันมาก


0

ฉันได้รับข้อผิดพลาดเดียวกันเมื่อพยายามคัดลอก csv ที่สร้างโดย Excel ไปยังตาราง Postgres (ทั้งหมดบน Mac) นี่คือวิธีที่ฉันแก้ไข:

1) เปิดไฟล์ใน Atom (IDE ที่ฉันใช้)

2) ทำการเปลี่ยนแปลงเล็กน้อยในไฟล์ บันทึกไฟล์ เลิกทำการเปลี่ยนแปลง บันทึกอีกครั้ง

โอมเพี้ยง! คำสั่งคัดลอกใช้งานได้แล้ว

(ฉันคิดว่า Atom บันทึกในรูปแบบที่ใช้งานได้)


0

เปิดไฟล์ CSV โดย Notepad ++ เลือกเมนูEncoding\ Encoding in UTF-8แล้วแก้ไขเซลล์ไม่กี่เซลล์ด้วยตนเอง

จากนั้นลองนำเข้าอีกครั้ง


0

หาก CSV ของคุณจะถูกส่งออกจาก SQL Server จะมีขนาดใหญ่มากและมีอักขระ Unicode คุณสามารถส่งออกได้โดยตั้งค่าการเข้ารหัสเป็นUTF-8:

Right-Click DB > Tasks > Export > 'SQL Server Native Client 11.0' >> 'Flat File Destination > File name: ... > Code page: UTF-8 >> ...

ในหน้าถัดไประบบจะถามว่าคุณต้องการคัดลอกข้อมูลจากตารางหรือคุณต้องการเขียนแบบสอบถาม ถ้าคุณมีcharหรือชนิดข้อมูลในตารางของคุณเลือกตัวเลือกการค้นหาและโยนคอลัมน์เหล่านั้นเป็นvarchar nvarchar(max)เช่นถ้าmyTableมีสองคอลัมน์โดยที่คอลัมน์แรกคือvarcharและคอลัมน์ที่สองintฉันจะส่งคอลัมน์แรกไปที่nvarchar:

select cast (col1 as nvarchar(max)) col1
       , col2
from myTable
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.