python - Pyspark - UnicodeEncodeError : 'ascii' codec can't encode character

标签 python python-2.7 apache-spark pyspark cx-oracle

在尝试将数据插入 Oracle DB 时运行以下程序时出现 unicodeerror

# -*- coding: utf-8 -*-
#import unicodedata
from pyspark.sql import SparkSession
from pyspark.sql import SQLContext
from pyspark.sql.types import *
from pyspark.sql.functions import udf
import sys
print(sys.getdefaultencoding())

u = 'abcdé'
a = 'Austròalia'
print(u)
print(a)

spark = SparkSession.builder.master("local") \
        .appName("Unicode_Error") \
        .getOrCreate()

sqlContext = SQLContext(spark)

l = [(340, 'India',1),(340, 'Canada',2),(341, u'abcdé',3),(340, 'Japan',4),(341, u'Austròalia',5),(341, 'China',6)]
df = sqlContext.createDataFrame(l, ['CUSTOMER_ID', 'COUNTRY', 'LINENUMBER'])
df.show()

data_tuples = [tuple(x) for x in df.rdd.collect()]

print(str(data_tuples))

print(type(data_tuples))

query = "INSERT INTO CUSTOMERS VALUES (:1, :2, :3)"
cur = con.cursor()
cur.prepare(query)
cur.executemany(None, data_tuples)
con.commit()
cur.close()
con.close()

在提交 Spark 作业之前设置了 PYTHONIOENCODING=utf8,这解决了 dataframe.show() 的问题。还有 # -*-coding: utf-8 -*- 帮助解决了 python print 语句。

尽管现在即使数据框正确显示数据,我也会收到错误。将数据框转换为列表是容易出现问题的地方,请您告知还需要做什么。

ascii
abcdé
Austròalia
+-----------+----------+----------+
|CUSTOMER_ID|   COUNTRY|LINENUMBER|
+-----------+----------+----------+
|        340|     India|         1|
|        340|    Canada|         2|
|        341|     abcdé|         3|
|        340|     Japan|         4|
|        341|Austròalia|         5|
|        341|     China|         6|
+-----------+----------+----------+

[(340, u'India', 1), (340, u'Canada', 2), (341, u'abcd\xe9', 3), (340, u'Japan', 4), (341, u'Austr\xf2alia', 5), (341, u'China', 6)]
<type 'list'>

> Traceback (most recent call last): cur.executemany(None, data_tuples)
> UnicodeEncodeError: 'ascii' codec can't encode character u'\xe9' in
> position 4: ordinal not in range(128)

元组列表具有 unicode 数据,并且无法使用 encode ,但打印出元组列表中的每个元素给了我如下的确切输出

[('340', "u'India'", '1'), ('340', "u'Canada'", '2'), ('341', "u'abcd\\xe9'", '3'), ('340', "u'Japan'", '4'), ('341', "u'Austr\\xf2alia'", '5'), ('341', "u'China'", '6')]
***********************
India
340
India
1
340
Canada
2
341
abcdé
3
340
Japan
4
341
Austròalia
5
341
China
6

最佳答案

通过 cx_Oracle 连接到 Oracle 时传递附加参数解决了这个问题。

设置Python环境的编码方法以支持Unicode数据处理

# -*- coding: utf-8 -*-
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

在 cx_Oracle 连接中提供编码属性

con = cx_Oracle.connect(connection_string, encoding = "UTF-8", nencoding = "UTF-8")

您可以引用https://github.com/oracle/python-cx_Oracle/issues/36以获得更多相同的想法。

关于python - Pyspark - UnicodeEncodeError : 'ascii' codec can't encode character,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53444073/

相关文章:

jar - 使用 sbt 程序集创建 fat jar 时出现 OutofMemoryErrory

python - py3 中的 OpenCV Python : how to avoid cv2. imwrite() 内存 "leak"?

python - 如何在 python 中逐行获取 MySQL ResultSet

python - 使用 python 2.7 从并行目录导入

python - 搜索坐标是否在立方体内部的最快方法

java - 如何将 Object[] 转换为 Row[]?

apache-spark - groupByKey 与 hashPartitioner 和 mapPartitions?

javascript - 使用ajax时Django不渲染数据

python - 如何修复此无效语法错误

python - 如何使 C 包装器(用 32 位 Python 编写)在运行 64 位 Python 的新机器上工作?