我必须将信息从PostgreSQL服务器(我们没有任何控制权)下载到CSV进行一些非关键的分析(基本上我们是在寻找包含任何行或列中特定字符串的表),所以我决定使用Pandas read_sql_table来实现这一点,但是我一直在一些表上得到一个UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0 in position 7: invalid start byte
错误,在对其他问题进行研究之后,我已经将客户端编码更改为UTF8,但是错误仍然发生。服务器编码是SQL_ASCII。
我的脚本的简化版本如下所示:
ENCODING = 'utf8'
conn_str = f"postgresql+psycopg2://{config['DBUSER']}:{config['DBPASS']}@{config['DBHOST']}/{config['DBNAME']}"
engine = create_engine(conn_str, client_encoding=ENCODING, pool_recycle=36000)
conn = engine.connect()
server = self.conn.execute("SHOW SERVER_ENCODING").fetchone()
print("Server Encoding ", server.server_encoding)
client = self.conn.execute("SHOW CLIENT_ENCODING").fetchone()
print("Client Encoding ", client.client_encoding)
df = pandas.read_sql_table(VIEWNAME, conn, SCHEMA)
产出:
Server Encoding SQL_ASCII
Client Encoding UNICODE
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xa0 in position 7: invalid start byte
据我所知,这个问题与底层的SQLAlchemy连接有关,所以我想在连接级别解决这个问题,如果不可能的话,我可以下载表中所有没有问题的行,但似乎不支持这样做。
发布于 2022-06-07 20:06:28
根据Postgres在这里的文档本地化/字符集
SQL_ASCII设置的行为与其他设置有很大不同。当服务器字符集为SQL_ASCII时,服务器根据ASCII标准解释字节值0-127,而字节值128-255被视为未解释字符。当设置为SQL_ASCII时,将不进行编码转换。因此,这个设置与其说是一个特定编码正在使用的声明,不如说是对编码无知的声明。在大多数情况下,如果您正在处理任何非ASCII数据,使用SQL_ASCII设置是不明智的,因为PostgreSQL将无法通过转换或验证非ASCII字符来帮助您。
这意味着,一旦获得ASCII 127,数据就可以以多种编码形式出现。通常情况下,数据是作为Windows代码页输入的。如果你知道数据最初是从哪里来的,也许可以缩小选择范围。然后,您可以尝试将client_encoding
设置为适当的代码页,以查看导出是否成功。
向前看,把server_encoding
从SQL_ASCII
上移开是个好主意,这样可以让生活更轻松。
https://stackoverflow.com/questions/72532745
复制相似问题