2014-06-12 19 views
7

Tôi đã thực hiện khá nhiều vấn đề về lỗi này và đã đun sôi nó xuống thực tế là cơ sở dữ liệu tôi đang làm việc có trong các mã hóa khác nhau.psycopg2.DataError: chuỗi byte không hợp lệ để mã hóa "UTF8": 0xa0

Máy chủ AIX tôi đang làm việc với đang chạy

psql 8.2.4 

server_encoding     | LATIN1   |  | Client Connection Defaults/Locale and Formatting    | Sets the server (database) character set encoding. 

Các cửa sổ 2008 R2 máy chủ tôi đang làm việc với đang chạy

psql (9.3.4)

CREATE DATABASE postgres 
WITH OWNER = postgres 
    ENCODING = 'UTF8' 
    TABLESPACE = pg_default 
    LC_COLLATE = 'English_Australia.1252' 
    LC_CTYPE = 'English_Australia.1252' 
    CONNECTION LIMIT = -1; 

COMMENT ON DATABASE postgres 
IS 'default administrative connection database'; 

Bây giờ khi tôi thử thực thi kịch bản python dưới đây của tôi Tôi nhận được lỗi này

Traceback (most recent call last): 
File "datamain.py", line 39, in <module> 
sys.exit(main()) 
File "datamain.py", line 33, in main 
write_file_to_table("cms_jobdef.txt", "cms_jobdef", con_S104838) 
File "datamain.py", line 21, in write_file_to_table 
cur.copy_from(f, table, ",") 
psycopg2.DataError: invalid byte sequence for encoding "UTF8": 0xa0 
CONTEXT: COPY cms_jobdef, line 15209  

Đây là kịch bản của tôi

import psycopg2 
import StringIO 
import sys 
import pdb 

def connect_db(db, usr, pw, hst, prt): 
    conn = psycopg2.connect(database=db, user=usr, 
    password=pw, host=hst, port=prt) 
    return conn 

def write_table_to_file(file, table, connection): 
    f = open(file, "w") 
    cur = connection.cursor() 
    cur.copy_to(f, table, ",") 
    f.close() 
    cur.close() 

def write_file_to_table(file, table, connection): 
    f = open(file,"r") 
    cur = connection.cursor() 
    cur.copy_from(f, table, ",") 
    f.close() 
    cur.close() 

def main(): 
    login = open('login.txt','r') 
    con_tctmsv64 = connect_db("x", "y", 
    login.readline().strip(), 
    "d.domain", "c") 
    con_S104838 = connect_db("x", "y", "z", "a", "b") 
    try: 
     write_table_to_file("cms_jobdef.txt", "cms_jobdef", con_tctmsv64) 
     write_file_to_table("cms_jobdef.txt", "cms_jobdef", con_S104838) 
    finally: 
     con_tctmsv64.close() 
     con_S104838.close() 

if __name__ == "__main__": 
    sys.exit(main()) 

đã xóa một số dữ liệu nhạy cảm.

Vì vậy, tôi không chắc chắn cách tôi có thể tiếp tục. Theo như tôi có thể nói, phương pháp copy_expert có thể trợ giúp bằng cách xuất dưới dạng mã hóa UTF8. Nhưng bởi vì các máy chủ tôi kéo dữ liệu từ đang chạy 8.2.4 Tôi không nghĩ rằng nó hỗ trợ định dạng mã hóa COPY.

Tôi nghĩ rằng bức ảnh đẹp nhất của tôi là thử và cài đặt lại cơ sở dữ liệu postgre bằng mã hóa LATIN1 trên máy chủ Windows. Khi tôi cố gắng và làm điều đó tôi nhận được lỗi dưới đây.

psql error

Vì vậy, im khá khó khăn, mọi trợ giúp sẽ được đánh giá cao!

Cập nhật Tôi đã cài đặt db postgre trên các cửa sổ dưới dạng mã hóa LATIN1 bằng cách thay đổi địa phương mặc định thành 'C'. tuy nhiên điều này đã cho tôi những lỗi dưới đây và doesnt có vẻ giống như một cách tiếp cận có khả năng thành công/đúng

enter image description here

Tôi cũng đã thử mã hóa các tập tin trong Binary sử dụng psql COPY chức năng

def write_table_to_file(file, table, connection): 
    f = open(file, "w") 
    cur = connection.cursor() 
    #cur.copy_to(f, table, ",") 
    cur.copy_expert("COPY cms_jobdef TO STDOUT WITH BINARY", f) 
    f.close() 
    cur.close() 

def write_file_to_table(file, table, connection): 
    f = open(file,"r") 
    cur = connection.cursor() 
    #cur.copy_from(f, table) 
    cur.copy_expert("COPY cms_jobdef FROM STDOUT WITH BINARY", f) 
    f.close() 
    cur.close() 

Vẫn không có may mắn Tôi gặp lỗi tương tự

DataError: invalid byte sequence for encoding "UTF8": 0xa0 
CONTEXT: COPY cms_jobdef, line 15209, column descript 

Liên quan đến câu trả lời Phil Tôi đã thử cách tiếp cận này với vẫn không có su ccess.

import psycopg2 
import StringIO 
import sys 
import pdb 
import codecs 

def connect_db(db, usr, pw, hst, prt): 
    conn = psycopg2.connect(database=db, user=usr, 
    password=pw, host=hst, port=prt) 
    return conn 

def write_table_to_file(file, table, connection): 
    f = open(file, "w") 
    #fx = codecs.EncodedFile(f,"LATIN1", "UTF8") 
    cur = connection.cursor() 
    cur.execute("SHOW client_encoding;") 
    print cur.fetchone() 
    cur.copy_to(f, table) 
    #cur.copy_expert("COPY cms_jobdef TO STDOUT WITH BINARY", f) 
    f.close() 
    cur.close() 

def write_file_to_table(file, table, connection): 
    f = open(file,"r") 
    cur = connection.cursor() 
    cur.execute("SET CLIENT_ENCODING TO 'LATIN1';") 
    cur.execute("SHOW client_encoding;") 
    print cur.fetchone() 
    cur.copy_from(f, table) 
    #cur.copy_expert("COPY cms_jobdef FROM STDOUT WITH BINARY", f) 
    f.close() 
    cur.close() 

def main(): 
    login = open('login.txt','r') 
    con_tctmsv64 = connect_db("x", "y", 
    login.readline().strip(), 
    "ctmtest1.int.corp.sun", "5436") 
    con_S104838 = connect_db("x", "y", "z", "t", "5432") 
    try: 
     write_table_to_file("cms_jobdef.txt", "cms_jobdef", con_tctmsv64) 
     write_file_to_table("cms_jobdef.txt", "cms_jobdef", con_S104838) 
    finally: 
     con_tctmsv64.close() 
     con_S104838.close() 

if __name__ == "__main__": 
    sys.exit(main()) 

đầu ra

In [4]: %run datamain.py 
('sql_ascii',) 
('LATIN1',) 

In [5]: 

này hoàn tất thành công nhưng khi tôi chạy một Không có gì

select * from cms_jobdef; 

là trong cơ sở dữ liệu mới

enter image description here

Tôi thậm chí đã thử chuyển đổi định dạng tệp từ LATIN1 sang UTF8.Vẫn không có may mắn

Điều kỳ lạ là khi tôi thực hiện quy trình này theo cách thủ công bằng cách chỉ sử dụng chức năng postgre COPY hoạt động. Tôi không biết tại sao. Một lần nữa, bất kỳ sự trợ giúp nào cũng sẽ được đánh giá cao.

Trả lời

4

Tôi đang trong quá trình di chuyển từ cơ sở dữ liệu SQL_ASCII sang cơ sở dữ liệu UTF8 và gặp sự cố tương tự. Dựa trên this answer, tôi chỉ đơn giản là thêm vào bản Tuyên Bố này để bắt đầu kịch bản nhập của tôi:

set client_encoding to 'latin1' 

và mọi thứ dường như đã nhập khẩu một cách chính xác.

+0

Xin chào Phil cảm ơn phản hồi của bạn. Tôi cũng đã thử điều đó và không thành công. Mã thực hiện thành công nhưng bảng vẫn còn trống sau khi nó thực thi. Tôi đã cập nhật câu hỏi ban đầu của mình để phản ánh điều này –

+1

Tôi ghét hỏi điều này ... bạn có cam kết giao dịch của mình không? http://initd.org/psycopg/docs/connection.html nói "Theo mặc định, Psycopg mở một giao dịch trước khi thực hiện lệnh đầu tiên: nếu commit() không được gọi, hiệu ứng của bất kỳ thao tác dữ liệu nào sẽ bị mất." –

+0

Cảm ơn bạn đã phản hồi Phil bạn đã giúp đỡ rất nhiều! –

4

Hóa ra có một số tùy chọn để giải quyết vấn đề này.

Tùy chọn thay đổi mã hóa khách hàng được đề xuất bởi Phil không hoạt động.

cur.execute("SET CLIENT_ENCODING TO 'LATIN1';") 

Một tùy chọn khác là chuyển đổi dữ liệu nhanh chóng. Tôi đã sử dụng một mô-đun python được gọi là codec để làm điều này.

f = open(file, "w") 
fx = codecs.EncodedFile(f,"LATIN1", "UTF8") 
cur = connection.cursor() 
cur.execute("SHOW client_encoding;") 
print cur.fetchone() 
cur.copy_to(fx, table) 

Điểm mấu chốt là

fx = codecs.EncodedFile(f,"LATIN1", "UTF8") 

Vấn đề chính của tôi là tôi đã không cam kết thay đổi của tôi với cơ sở dữ liệu! Silly me :)

Các vấn đề liên quan