提问人:Justin Mathew 提问时间:2/8/2023 最后编辑:DataJanitorJustin Mathew 更新时间:11/22/2023 访问量:1719
将带有浮点值的 pandas 数据帧插入到 Oracle 中
Inserting pandas dataframe with float values into Oracle
问:
我可以从 pandas 数据帧将整数、字符串等正常值插入 Oracle 中,但是当我尝试浮点类型值时,sqlalchemy 给出以下错误
sqlalchemy.exc.ArgumentError: Oracle FLOAT types use 'binary precision', which does not convert cleanly from decimal 'precision'. Please specify this type with a separate Oracle variant, such as Float(precision=53).with_variant(oracle.FLOAT(binary_precision=176), 'oracle'), so that the Oracle specific 'binary_precision' may be specified accurately.
这是完整的源代码
import pandas as pd
import os
import sqlalchemy as sa
from sqlalchemy import text
from sqlalchemy.dialects import oracle
oracle_db = sa.create_engine('oracle://username:password@instance/?service_name=MBCDFE')
conn = oracle_db.connect()
df = pd.DataFrame({
#"column1": [1, 1, 1], #- inserting into DB works with just numbers
"column1": [1.2, 1.2, 1.2],
"column2": ["a", "bb", "c"],
"column3": ["K", "L", "M"]
})
df.to_sql("python", conn, if_exists="replace", index=True)
conn.commit()
conn.close()
任何帮助将不胜感激。非常感谢。
答:
要使 Oracle 了解数字是浮点格式,您需要将其转换为文本格式并将点替换为逗号。在 Oracle 中以 NUMBER 格式的表中,它将被很好地添加。
要修改您的号码,您可以执行以下操作:
df["column1"] = df["column1"].astype(str).str.replace('.', ',')
如果有几列包含浮点数据,则必须分别对每一列执行此方法。
评论
您遇到的错误是由于使用 SQLAlchemy 时处理 Pandas 和 Oracle 之间的数据类型时存在差异。Oracle 对 FLOAT 类型使用“二进制精度”,这与 Pandas 中使用的十进制精度不直接兼容。以下是解决此问题的方法:
在 to_sql中使用 dtype:在调用 to_sql 方法时为 DataFrame 列指定适当的数据类型。可以使用 sqlalchemy.types.Float 根据 Oracle 的要求以二进制精度定义数据类型。
下面是修改后的代码片段:
from sqlalchemy.types import Float
df.to_sql(
"python",
conn,
if_exists="replace",
index=True,
dtype={
"column1": Float(binary_precision=53),
# Define other data types for other columns if necessary
}
)
在本例中,Float(binary_precision=53) 定义 column1 的数据类型,其二进制精度适用于 Oracle。
数据一致性检查:确保 DataFrame 中的数据与要定义的数据类型真正匹配。在本例中,column1 应包含可表示为 FLOAT 的值。
提交事务:您正确地使用 conn.commit() 来提交事务。这对于确保更改保存在数据库中非常重要。
资源管理:使用上下文管理器来处理连接可以更安全,以确保即使发生错误也会关闭连接。
with oracle_db.connect() as conn:
df.to_sql("python", conn, ...)
conn.commit()
尝试将这些更改合并到代码中,然后再次运行。这应该有助于解决通过 Pandas 和 SQLAlchemy 将浮点类型数据插入 Oracle 的问题。
评论
sqlalchemy.types
sqlalchemy.types.Float
df.dtypes.unique()
df.dtypes
map