提问人:Lyla 提问时间:11/17/2023 最后编辑:Sandra RossiLyla 更新时间:11/17/2023 访问量:29
在 python 和 SQL 中将数据从 pandas 数据帧有条件地插入到 HANA 表
Conditional inserting of data from pandas data frame to HANA table in python and SQL
问:
不幸的是,我无法找到解决方案,这就是为什么我希望你能帮助我。
鉴于:
我在HANA中有一个名为的表。
它如下所示:( = 主键)Table_1
ID
编号 | COL1型 | 名字 | COL2型 |
---|---|---|---|
1 | someValue | 一个 | someValue |
2 | someValue | B | someValue |
我有一个 CSV 文件,其中包含未知数量的列和未知的列名称。我唯一知道的是,每个 CSV 文件都包含一个名为 和 的列。X_ID
X_NAME
我将此 CSV 文件读取到名为 .df
Df
如下所示:
X_ID | X_NAME | COL3型 | COL4型 | 山坳。。。 |
---|---|---|---|---|
1 | 一个 | someXValue | someXValue | ... |
2 | B | someXValue | someXValue | |
3 | C | someXValue | someXValue |
以下内容适用于 和 :Table_1
df
ID = X_ID and NAME = X_NAME
现在我想包括 to 的数据。df
Table_1
我尝试了合并、插入和更新插入,但不幸的是我无法获得正常运行的命令。
如果 已包含在 中,则只有 中的新列应追加到相应的行中。X_ID
ID
Table_1
df
如果不在,则应应用以下内容: ; 和 from 应为 null;并且应包括 中的所有附加列及其值。X_ID
ID
ID = X_ID, NAME = X_NAME
COL1
COL2
Table_1
df
解决方案应如下所示:
Table_1
:
编号 | COL1型 | 名字 | COL2型 | COL3型 | COL4型 | 山坳。。。 |
---|---|---|---|---|---|---|
1 | someValue | 一个 | someValue | someXValue | someXValue | ... |
2 | someValue | B | someValue | someXValue | someXValue | |
3 | 零 | C | 零 | someXValue | someXValue |
我已经尝试过的:
我目前的代码:
#!/usr/bin/python3
import pandas as pd
import argparse
from hdbcli import dbapi
parser = argparse.ArgumentParser(
prog='ABC',
description='XYZ')
parser.add_argument('input_filepath')
args = parser.parse_args()
df = pd.read_csv(args.input_filepath,sep=',')
conn = dbapi.connect(address='ADDRESS', port=PORT, user='USER', password='PSW')
target_table = 'TABLE_NAME'
sql_insert_template = f"""
ALTER TABLE {target_table}
ADD ({', '.join([f'{col} VARCHAR(200)' for col in df.columns if col != 'X_ID' and col != 'X_NAME'])});
# TODO: SQL Code for data inserting (at the bottom)
"""
try:
with conn.cursor() as cursor:
cursor.execute(sql_insert_template)
conn.commit()
print("Record inserted successfully")
finally:
conn.close()
我尝试以下SQL代码来插入数据:
MERGE INTO {target_table} AS target
USING (
SELECT
{', '.join(df.columns)}
FROM {df}
) AS source
ON (target.ID = source.X_ID)
WHEN MATCHED THEN
UPDATE {target_table}
SET {', '.join([f'target.{col} = source.{col}' for col in df.columns if col != 'X_ID' and col != 'X_NAME'])}
WHEN NOT MATCHED THEN
INSERT INTO {target_table}(
ID, NAME, {', '.join(f'{col}' for col in df.columns if col != 'X_ID' and col != 'X_NAME')}
) VALUES (
{', '.join([f'source.X_ID, source.X_NAME, source.{col}' for col in df.columns if col != 'X_ID' and col != 'X_NAME'])}
);
在此命令中,存在多个错误。第一个是我无法在 Merge 附近解决的语法错误,第二个是从 .因为现在在部分 “” 中,不是值,而是列名作为值包含在内,并且对行、列和值的迭代是错误的。所以现在只包含“一行”(一行,但有列名而不是值)。但是我想将所有行、值都包含在一个 SQL 命令中。df
WHEN NOT MATCHED THAN ... VALUES()
df
df
我真的不知道如何解决以正确的方式包含所有值的问题。
我尝试的第二种方法是使用 UPSET,但仍然存在包含值的问题。还有一个额外的当前问题,我需要知道有多少列,以便我可以设置“null”值。table_1
UPSERT {target_table}
VALUES({', '.join(f'{col}' for col in df.columns if col == 'X_ID')}, null, {', '.join(f'{col}' for col in df.columns if col == 'X_NAME')}, null, {', '.join(f'{col}' for col in df.columns if col != 'X_ID' and col != 'X_NAME')})
#WITH PRIMARY KEY;
答:
在使用 Pandas Dataframes 和 SAP HANA 时,我建议查看 hana-ml Python 包。它建立在 Pandas 的基础上,并显著改进了与 Pandas 的集成。查看 HANA 数据帧,特别是create_dataframe_from_pandas和保存的方法hdbcli
但是,这还不是解决您最初问题的方法。您选择的数据模型似乎并不完全适合您的用例。如果每个新表确实都带有任意属性,则最终将在 HANA 上得到一个非常宽且稀疏的表。在关系世界中,您可以考虑使用一个带有 和 的表,以及另一个带有引用公共属性的键值对的表。ID
NAME
使用 SAP HANA 的 JSON Document Store 会更容易,这是一个用于管理半结构化数据的原生引擎。在此方案中,您将在 Pandas 数据帧上使用 to_json,并在 中create_collection_from_elements。可以使用简单的 SQL 查询生成的 JSON 集合。hana-ml
评论