chuỗi byte không hợp lệ để mã hóa


124

Tôi đang cố gắng nhập một số dữ liệu vào cơ sở dữ liệu của mình. Vì vậy, tôi đã tạo một bảng tạm thời,

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

Và bây giờ tôi đang cố gắng nhập dữ liệu ,

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

Nhưng sau đó tôi nhận được lỗi,

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

Làm thế nào để tôi sửa nó? Tôi có cần thay đổi mã hóa toàn bộ cơ sở dữ liệu của mình không (nếu có, bằng cách nào?) Hoặc tôi có thể thay đổi chỉ mã hóa bảng của mình tmpkhông? Hoặc tôi nên cố gắng thay đổi mã hóa của tập tin?


thay đổi tùy chọn mã hóa khi nhập. Tôi đặt của tôi thành "Windows-1251" và nó hoạt động mà không có khiếu nại.
Brian D

1
Cảm ơn @BrianD, tôi cũng đã đối mặt với vấn đề này và điều này đã làm việc cho tôi.
gouravkr

Câu trả lời:


109

Nếu bạn cần lưu trữ dữ liệu UTF8 trong cơ sở dữ liệu của mình, bạn cần một cơ sở dữ liệu chấp nhận UTF8. Bạn có thể kiểm tra mã hóa cơ sở dữ liệu của bạn trong pgAdmin. Chỉ cần nhấp chuột phải vào cơ sở dữ liệu và chọn "Thuộc tính".

Nhưng lỗi đó dường như đang nói với bạn rằng có một số dữ liệu UTF8 không hợp lệ trong tệp nguồn của bạn. Điều đó có nghĩa là copytiện ích đã phát hiện hoặc đoán rằng bạn đang cung cấp cho nó tệp UTF8.

Nếu bạn đang chạy dưới một số biến thể của Unix, bạn có thể kiểm tra mã hóa (nhiều hơn hoặc ít hơn) với filetiện ích.

$ file yourfilename
yourfilename: UTF-8 Unicode English text

(Tôi nghĩ rằng nó cũng sẽ hoạt động trên máy Mac trong thiết bị đầu cuối.) Không chắc chắn làm thế nào để làm điều đó trong Windows.

Nếu bạn sử dụng cùng một tiện ích trên một tệp đến từ các hệ thống Windows (nghĩa là một tệp không được mã hóa trong UTF8), nó có thể sẽ hiển thị một cái gì đó như thế này:

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

Nếu mọi thứ trở nên kỳ lạ, bạn có thể cố gắng chuyển đổi dữ liệu đầu vào của mình thành một mã hóa đã biết, để thay đổi mã hóa của khách hàng hoặc cả hai. (Chúng tôi thực sự mở rộng giới hạn kiến ​​thức của tôi về mã hóa.)

Bạn có thể sử dụng iconvtiện ích để thay đổi mã hóa dữ liệu đầu vào.

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

Bạn có thể thay đổi mã hóa psql (máy khách) theo hướng dẫn trên Hỗ trợ bộ ký tự . Trên trang đó, tìm kiếm cụm từ "Để bật chuyển đổi bộ ký tự tự động".


3
Nói tập tin là ASCII, nhưng nó chứa các ký tự có dấu, vậy có phải là sai không?
mở

2
Sẽ chấp nhận câu trả lời này, nhưng tôi nghĩ vấn đề thực sự nằm ở dữ liệu (cập nhật Q).
mở

1
Tôi thấy điều này hữu ích, cảm ơn. Nhân tiện, nó cũng chạy trên các thiết bị đầu cuối OS X
Raul Rene

1
Điều này làm việc cho tôi, nhưng theo một cách hơi khác. Lệnh "iconv" thực sự đánh bom vào tập tin của tôi, nhưng nó đã xử lý đúng vấn đề - một loại ký tự "-" kỳ lạ. Dù sao, tôi đã loại bỏ điều đó và tập tin của tôi đã có thể tải vào postgres. Cảm ơn vì tiền hỗ trợ!
trip0d199

1
Chỉ để giúp đỡ người khác và các công cụ tìm kiếm: công cụ này hoạt động để chuyển đổi xuất CSV Stripe với các ký tự không thể đọc được thành UTF-8: `iconv -f ISO-8859-15 -t utf-8 customer.csv> khách hàng-utf8.csv`
sscarduzio

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

Thêm encodingtùy chọn làm việc trong trường hợp của tôi.


1
nó sẽ hoàn thành mà không có lỗi, nó có thể hoặc không thể cho kết quả hữu ích. bạn cần biết mã hóa dự định của dữ liệu.
Jasen

1
Trong kịch bản của tôi, làm thế nào truy vấn trên làm việc? Tôi có tệp csv được mã hóa bằng UTF8 và DB được mã hóa bằng UTF8.
Ajay Takur

14

Rõ ràng tôi chỉ có thể thiết lập mã hóa một cách nhanh chóng,

 set client_encoding to 'latin1'

Và sau đó chạy lại truy vấn. Không chắc chắn những gì tôi nên sử dụng mã hóa mặc dù.


latin1làm cho các nhân vật trở nên rõ ràng, nhưng hầu hết các nhân vật có dấu đều ở dạng chữ hoa mà họ không nên có. Tôi cho rằng điều này là do mã hóa xấu, nhưng tôi nghĩ rằng nó thực sự là dữ liệu xấu. Tôi đã kết thúc việc giữ mã hóa latin1, nhưng xử lý trước dữ liệu và khắc phục các sự cố vỏ.


Thật thú vị, tôi đã nhận được lỗi trên một câu lệnh CHỌN! Điều này đã giải quyết nó bởi vì đó là máy khách psql của tôi đưa ra lỗi chứ không phải cơ sở dữ liệu. (Việc từ chối dữ liệu ở nơi đầu tiên có mã hóa bị cấm.)
Wildcard

14

Nếu bạn ổn với việc loại bỏ các ký tự không thể chuyển đổi, bạn có thể sử dụng -ccờ

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

và sau đó sao chép chúng vào bảng của bạn


Trên Mac, nó là iconv -c -t UTF-8 filename.csv > filename.utf8.csvdành cho tôi
Michael

8

Lỗi này có nghĩa là bản ghi mã hóa trong tệp khác với kết nối. Trong trường hợp này iconv có thể trả về lỗi, đôi khi thậm chí mặc dù // cờ IGNORE:

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

iconv: chuỗi đầu vào bất hợp pháp tại vị trí (một số)

Bí quyết là tìm các ký tự không chính xác và thay thế nó. Để làm điều đó trên Linux, hãy sử dụng trình soạn thảo "vim":

vim (tệp văn bản của bạn), nhấn "ESC": nút và gõ ": goto (số được trả về bởi iconv)"

Để tìm các ký tự không phải ASCII, bạn có thể sử dụng lệnh sau:

grep --color = 'tự động' -P "[\ x80- \ xFF]"

Nếu bạn xóa các ký tự không chính xác, vui lòng kiểm tra xem bạn có thực sự cần chuyển đổi tệp của mình không: có lẽ vấn đề đã được giải quyết.


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

5

làm theo các bước dưới đây để giải quyết vấn đề này trong pgadmin:

  1. SET client_encoding = 'ISO_8859_5';

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


4

Nó phụ thuộc vào loại máy / mã hóa tạo tệp nhập của bạn.

Nếu bạn nhận được nó từ phiên bản Windows tiếng Anh hoặc Tây Âu, thì cách tốt nhất của bạn có lẽ là đặt nó thành 'WIN1252'. Nếu bạn nhận được nó từ một nguồn khác, hãy tham khảo danh sách mã hóa ký tự ở đây:

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

Nếu bạn nhận được nó từ máy Mac, trước tiên bạn có thể phải chạy nó thông qua tiện ích "iconv" để chuyển đổi nó từ MacRoman sang UTF-8.


4

Vâng, tôi đã phải đối mặt với cùng một vấn đề. Và điều giải quyết vấn đề của tôi là đây:

Trong excel bấm vào Save as. Từ lưu dưới dạng, chọn .csv Nhấp vào Công cụ . Sau đó chọn tùy chọn web từ danh sách thả xuống. Trong tab Mã hóa , lưu tài liệu dưới dạng Unicode (UTF-8) . Nhấn OK. Lưu các tập tin. LÀM XONG !


3

Tôi đã có cùng một vấn đề, và tìm thấy một giải pháp tốt đẹp ở đây: http://blog.e-shell.org/134

Điều này được gây ra bởi sự không phù hợp trong mã hóa cơ sở dữ liệu của bạn, chắc chắn là do cơ sở dữ liệu từ nơi bạn nhận kết xuất SQL được mã hóa thành SQL_ASCII trong khi cơ sở dữ liệu mới được mã hóa dưới dạng UTF8. .. Recode là một công cụ nhỏ từ dự án GNU cho phép bạn thay đổi mã hóa của một tệp đã cho.

Vì vậy, tôi chỉ mã hóa dumpfile trước khi phát lại:

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

Trong các hệ thống Debian hoặc Ubuntu, recode có thể được cài đặt thông qua gói.


2

Bạn có thể thay thế ký tự dấu gạch chéo ngược, ví dụ như ký tự ống, bằng sed.

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

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

bạn có thể thử điều này để xử lý mã hóa UTF8.


2

Ví dụ ngắn để giải quyết vấn đề này trong PHP-

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

Chi tiết lỗi: Vì cơ sở dữ liệu POSTGRES không xử lý ngoài các ký tự UTF-8 khi chúng tôi cố gắng chuyển các đầu vào đã cho ở trên vào cột, nó đưa ra lỗi "chuỗi byte không hợp lệ để mã hóa" UTF8 ": 0xab".

Vì vậy, chỉ cần chuyển đổi giá trị đó thành UTF-8 trước khi chèn vào Cơ sở dữ liệu POSTGRES.


2

Tôi gặp vấn đề tương tự: tập tin của tôi không được mã hóa dưới dạng UTF-8. Tôi đã giải quyết nó bằng cách mở tệp bằng notepad ++ và thay đổi mã hóa của tệp.

Chuyển đến "Mã hóa" và chọn "Chuyển đổi sang UTF-8". Lưu các thay đổi và đó là tất cả!


1

Lỗi này có thể xảy ra nếu dữ liệu đầu vào chứa ký tự thoát. Theo mặc định, ký tự thoát là ký hiệu "\", vì vậy nếu văn bản đầu vào của bạn chứa ký tự "\" - hãy thử thay đổi giá trị mặc định bằng tùy chọn ESCAPE.


1

Đối với python, bạn cần sử dụng

Lớp pg8000.types.Bytea (str) Bytea là một lớp có nguồn gốc str được ánh xạ tới một mảng byte PostgreQuery.

hoặc là

PG8000.Binary (value) Xây dựng một đối tượng chứa dữ liệu nhị phân.


1

Tôi gặp vấn đề này trong Windows trong khi làm việc riêng với psql (không có công cụ đồ họa). Để khắc phục sự cố này, thay đổi vĩnh viễn mã hóa mặc định của psql (máy khách) để phù hợp với mã hóa mặc định của máy chủ PostgreQuery. Chạy lệnh sau trong CMD hoặc Powershell:

setx PGCLIENTENCODING UTF8

Đóng và mở lại bạn nhắc lệnh / Powershell để thay đổi có hiệu lực.

Thay đổi mã hóa tệp sao lưu từ Unicode sang UTF8 bằng cách mở tệp bằng Notepad và chuyển đến Tệp -> Lưu dưới dạng. Thay đổi thả xuống Mã hóa từ Unicode sang UTF8. (Đồng thời thay đổi loại Lưu dưới dạng từ Tài liệu văn bản (.txt) thành Tất cả các tệp để tránh thêm phần mở rộng .txt vào tên tệp sao lưu của bạn). Bây giờ bạn có thể khôi phục lại bản sao lưu của bạn.


0

Cũng có thể với lỗi này là trường được mã hóa tại chỗ. Hãy chắc chắn rằng bạn đang nhìn vào bảng bên phải, trong một số trường hợp, quản trị viên sẽ tạo một chế độ xem không được mã hóa mà bạn có thể sử dụng thay thế. Gần đây tôi đã gặp một vấn đề rất giống nhau.


0

Tôi đã gặp lỗi tương tự khi tôi đang cố sao chép một csv do Excel tạo ra vào bảng Postgres (tất cả trên máy Mac). Đây là cách tôi giải quyết nó:

1) Mở tệp trong nguyên tử (IDE mà tôi sử dụng)

2) Thực hiện một thay đổi không đáng kể trong tập tin. Lưu các tập tin. Hoàn tác thay đổi. Lưu lại.

Mau! Lệnh sao chép làm việc ngay bây giờ.

(Tôi nghĩ rằng Atom đã lưu nó ở định dạng hoạt động)


0

Mở tệp CSV bằng Notepad ++. Chọn menu Encoding\ Encoding in UTF-8, sau đó sửa vài ô.

Sau đó thử nhập lại.


0

Nếu CSV của bạn sẽ được xuất từ ​​SQL Server, nó rất lớn và nó có các ký tự Unicode, bạn có thể xuất nó bằng cách đặt mã hóa là UTF-8:

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

Trong trang tiếp theo, nó hỏi bạn có muốn sao chép dữ liệu từ một bảng hay bạn muốn viết một truy vấn. Nếu bạn có charhoặc varcharloại dữ liệu trong bảng của mình, hãy chọn tùy chọn truy vấn và truyền các cột đó thành nvarchar(max). Ví dụ: nếu myTablecó hai cột trong đó cột thứ nhất varcharvà cột thứ hai int, tôi chuyển cột đầu tiên sang nvarchar:

select cast (col1 as nvarchar(max)) col1
       , col2
from myTable
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.