如何使用Python(没有PySpark)将pandas数据帧插入现有的配置单元外部表?
我正在创建一个到配置单元的连接字符串,并在该连接上的配置单元表上运行一些SELECT查询 在对检索到的数据执行一些转换之后,我正在创建一个数据框如何使用Python(没有PySpark)将pandas数据帧插入现有的配置单元外部表?,python,pandas,dataframe,hive,Python,Pandas,Dataframe,Hive,我正在创建一个到配置单元的连接字符串,并在该连接上的配置单元表上运行一些SELECT查询 在对检索到的数据执行一些转换之后,我正在创建一个数据框df_student_credits,如下所示 NAME_STUDENT_INITIAL CREDITS_INITIAL NAME_STUDENT_FINAL CREDITS_FINAL LOAD_DATE John 23 John
df_student_credits
,如下所示
NAME_STUDENT_INITIAL CREDITS_INITIAL NAME_STUDENT_FINAL CREDITS_FINAL LOAD_DATE
John 23 John 25 21/03/2017
Alan 19 Alan 19 17/06/2018
Will 24 Will 26 02/08/2019
Lily 25 Lily 25 22/01/2019
现在,我想将此数据框插入到使用以下命令创建的配置单元外部表中:
CREATE EXTERNAL TABLE IF NOT EXISTS school_db.student_credits
(
NAME_STUDENT_INITIAL STRING,
CREDITS_INITIAL STRING,
NAME_STUDENT_FINAL STRING,
CREDITS_FINAL STRING,
LOAD_DATE STRING
)
LOCATION '/user/gradebook/student_credits/';
我希望每次运行此脚本并生成dataframe时,插入都被追加到表中,而不是覆盖现有的表数据
我看到的几乎每一篇文章都展示了使用PySpark实现这一点的方法。但是我不能使用PySpark,我必须使用与触发SELECT查询相同的python脚本来实现这一点
我对Hive非常陌生,是Python的新手。有人能帮我解决这个问题吗?在我得到确切答案之前,这里有一些建议 没有分区,HDFS什么都不是。在您的情况下,您还没有定义任何分区。将其作为默认设置从来都不是一个好主意。这是您的数据,您必须知道如何对其进行分区。因此,添加一个适当的分区by子句 假设LOAD_DATE是要设置分区的列。将数据帧转储为拼花格式。 对于HDFS数据,我保持与拼花地板路径相同的路径。 现在按如下所示:
CREATE EXTERNAL TABLE IF NOT EXISTS school_db.student_credits
(
NAME_STUDENT_INITIAL STRING,
CREDITS_INITIAL STRING,
NAME_STUDENT_FINAL STRING,
CREDITS_FINAL STRING
)
partitioned by (LOAD_DATE STRING
ROW FORMAT SERDE 'parquet.hive.serde.ParquetHiveSerDe'
STORED AS
INPUTFORMAT "parquet.hive.DeprecatedParquetInputFormat"
OUTPUTFORMAT "parquet.hive.DeprecatedParquetOutputFormat"
location '/user/gradebook/student_credits';
set hive.msck.path.validation=ignore;
msck repair table school_db.student_credits;
这里的修复
命令是您每天需要启动的命令。这将刷新数据和新分区
关于如何将数据框转储到拼花地板文件中,请使用以下命令
df_student_credits.write.mode("append").partitionBy("LOAD_DATE").parquet("user/gradebook/student_credits")
首先创建拼花地板文件,然后创建外部桌子。
让我知道这是否解决了您的问题您似乎正在尝试从配置单元表读入pandas数据帧,并进行一些转换并将其保存回某个配置单元外部表。请参考以下代码作为示例。在这里,我将Hive表中的数据读取到pandas数据框中,并在其中添加了一些日期列。后来,我使用子流程模块来执行shell,它将数据加载到配置单元表中,配置单元表在某个日期列上进行了分区
from pyhive import hive
import pandas as pd
import sqlalchemy
from sqlalchemy.engine import create_engine
import datetime
from subprocess import PIPE, Popen
import subprocess
import sys
conn = hive.Connection(host="yourhost.com", port=10000, username="vikct001")
cursor = conn.cursor()
query="select user_id,country from test_dev_db.test_data"
start_time= datetime.datetime.now()
output_file='/home/vikct001/user/vikrant/python/test_data.csv'
data=pd.read_sql(query,conn)
data['current_date'] = pd.datetime.today().strftime("%Y-%m-%d")
print(data)
data.to_csv(output_file, sep='|', encoding='utf-8',index=None)
hivequery=""" hive --hivevar loaded_date=$(date +"%Y-%m-%d") hive -e 'LOAD DATA LOCAL INPATH "/home/vikct001/user/vikrant/python/test_data.csv" INTO TABLE test_dev_db.test_data_external PARTITION (loaded_date="${hivevar:loaded_date}")';"""
def save_to_hdfs(output_file):
print("I am here")
p=subprocess.Popen(hivequery,shell=True,stderr=subprocess.PIPE)
stdout,stderr = p.communicate()
if p.returncode != 0:
print stderr
sys.exit(1)
save_to_hdfs(output_file)
end_time=datetime.datetime.now()
print 'processing ends', (start_time-end_time).seconds/60.0,' minutes'
表格说明:
hive (test_dev_db)> desc test_dev_db.test_data_external;
OK
id int
country string
input_date date
loaded_date string
# Partition Information
# col_name data_type comment
loaded_date string
您可以看到数据已经加载并创建了一个具有当前日期的分区
hive (test_dev_db)> show partitions test_dev_db.test_data_external;
OK
loaded_date=2019-08-21
hive (test_dev_db)> select * from test_dev_db.test_data_external;
OK
1 India 2019-08-21 2019-08-21
2 Ukraine 2019-08-21 2019-08-21
1 India 2019-08-21 2019-08-21
2 Ukraine 2019-08-21 2019-08-21
1 India 2019-08-21 2019-08-21
2 Ukraine 2019-08-21 2019-08-21
1 India 2019-08-21 2019-08-21
感谢您对分区和代码更改的建议。我会记住这一点。但是,我如何将数据框(例如
df_student_credits
)实际插入到这个配置单元表中呢?df_student_credits.write.mode(“append”).partitionBy(“LOAD_DATE”).parquet(“用户/成绩册/学生信用”)它说:'DataFrame'对象没有“write”属性。
关于如何解决这个问题有什么想法吗?可能是你可以用它来写入拼花格式。结果我需要用orc
格式而不是parquet来写入数据。
我有没有办法将我的数据框直接存储为一个orc
文件,存储在我在my Hive表创建中使用了,但没有使用PySpark?请在下面找到我的答案。确保为pandas dataframe选择的分隔符必须与create hive external table语句结尾的字段相匹配。Thanks@vikrantrana我无法完全使用您的答案,因为它需要我将数据集保存到csv中。我刚刚更新了你的答案,因为它确实给了我一些新的想法,我正在我的代码中尝试。非常感谢您的回复。如果我最终使用类似的逻辑来解决我的问题,我肯定会回来选择你的作为正确答案。哦,听起来不错。我以前不知道。我也会研究这个选择。非常感谢你提到这件事。