我有一个sqlite数据库,其中的列另存为json,有些只是数组,有些是对象数组 数据不是太大,一个表中大约有100万行,而另一个表中又有600万行。现在,我想提高查询速度并将这些数据提取到索引化且更易于管理的
问题是,spark将json列视为BigDecimal,但我不知道为什么或如何解决,发现了一些东西,但没有任何帮助。
Caused by: java.sql.SQLException: Bad value for type BigDecimal : [56641575300, 56640640900, 56640564100, 56640349700, 18635841800, 54913035400, 6505719940, 56641287800, 7102147726, 57202227222, 57191928343, 18633330200, 57193578904, 7409778074, 7409730079, 55740247200, 56641355300, 18635857700, 57191972388, 54912606500, 6601960745, 57191972907, 56641923500, 56640256300, 54911965100, 45661930800, 55474245300, 7409541556, 7409694518, 56641363000, 56519446200, 6504106170, 57191975866, 56640736700, 55463741500, 56640319300, 56640861000, 54911965000, 56561401800, 6504731849, 24342836300, 7402491855, 22950414800, 6507741522, 6504199636, 7102381436, 57191895642, 18634536800, 57196623329, 7005988322, 56013334500, 18634278500, 57191983462, 7409545828, 57204194408, 56641031400, 56641436400, 6504659572, 36829162100, 24766932600, 8256434300]
at org.sqlite.jdbc3.JDBC3ResultSet.getBigDecimal(JDBC3ResultSet.java:196)
我尝试的是加载sqlite驱动程序,然后使用SQLContext
df = sqlContext.read.format('jdbc').options(url='jdbc:sqlite:../cache/iconic.db', dbtable='coauthors', driver='org.sqlite.JDBC').load()
在spark抱怨列类型后,我尝试将其转换为字符串,以便可以将其进一步解析为json
schema = ArrayType(IntegerType())
df.withColumn('co_list', from_json(df['co_list'].cast(StringType()), schema))
但这会引发相同的错误,因为它没有更改任何内容
我也尝试从一开始就设置表架构,但似乎pyspark不允许我这样做
df = sqlContext.read.schema([...]).format('jdbc')...
# Throws
pyspark.sql.utils.AnalysisException: 'jdbc does not allow user-specified schemas.;'
行看起来像这样
# First table
1 "[{""surname"": ...}]" "[[{""frequency"": ""58123"", ...}]]" 74072 14586 null null null "{""affiliation-url"":}" "[""SOCI""]" null 0 0 1
# Second table
505 "[{""surname"": ""Blondel"" ...}, {""surname"": ""B\u0153ge"" ..}, ...]" "1999-12-01" 21 null null null 0
希望有办法。
答案 0 :(得分:0)
找到解决方案后,应使用jdbc阅读器加载数据库,并且要自定义列的转换,应将属性传递给驱动程序
这是解决方案
connectionProperties = {
"customSchema": 'id INT, co_list STRING, last_page INT, saved INT',
"driver": 'org.sqlite.JDBC'
}
df = sqlContext.read.jdbc(url='jdbc:sqlite:../cache/iconic.db', table='coauthors', properties=connectionProperties)
这样,您可以控制spark如何在内部映射数据库表的列。