Chr*_*ood 12 python pandas pyarrow
我是 Python 和 Pandas 的新手 - 请温柔一点!
我使用 SqlAlchemy 和 pymssql 对 SQL Server 数据库执行 SQL 查询,然后将结果集转换为数据帧。然后我尝试将此数据帧写入 Parquet 文件:
engine = sal.create_engine(connectionString)
conn = engine.connect()
df = pd.read_sql(query, con=conn)
df.to_parquet(outputFile)
Run Code Online (Sandbox Code Playgroud)
我在 SQL 查询中检索的数据包括一个uniqueidentifier名为 的列(即 UUID)rowguid。因此,我在上面的最后一行收到以下错误:
pyarrow.lib.ArrowInvalid: ("Could not convert UUID('92c4279f-1207-48a3-8448-4636514eb7e2') with type UUID: did not recognize Python value type when inferring an Arrow data type", 'Conversion failed for column rowguid with type object')
Run Code Online (Sandbox Code Playgroud)
有什么方法可以强制所有 UUID 在上述事件链中的任何点都串起来吗?
一些额外的注意事项:
df['rowguid'] = df['rowguid'].astype(str),但这依赖于我知道哪些列有uniqueidentifier类型。当它成为一个数据框时,一切都是一个object,每个查询都会不同。char(36)SQL 查询本身,但是,我希望做一些更“自动”的事情,这样编写查询的人就不会一直意外地遇到这个问题/不必这样做请记住始终转换数据类型。有任何想法吗?
尝试 DuckDB
尽管名称中有“DB”,DuckDB 是一个专门为数据分析任务设计的 Python 包,并不是完整的数据库替代品。它擅长处理数据类型转换,而无需使用 PyArrow 等库时可能遇到的自定义扩展。
import sqlalchemy as sal
import pandas as pd
import duckdb
# Define your SQL variables
connection_string = "your_connection_string_here"
query = "your_query_here"
# Connect to your SQL database using SQLAlchemy
engine = sal.create_engine(connection_string)
conn = engine.connect()
# Run your query and load the results into a DataFrame
df = pd.read_sql(query, con=conn)
# Close the SQL database connection
conn.close()
# My Solution
# With duckdb installed and imported implement the code below
output_file_path = "your_output_file_path_here"
# Connect to DuckDB in-memory
duck_conn = duckdb.connect(':memory:')
# Write the DataFrame (with complex types like UUID) to a
# snappy-compressed Parquet file with DuckDB
duck_conn.query(f"COPY df TO '{output_file_path}' (FORMAT PARQUET)")
# Close the DuckDB connection
duck_conn.close()
Run Code Online (Sandbox Code Playgroud)
供考虑的附加说明:
值得一提的是,有一些使用自定义 UUIDType 扩展 PyArrow 的方法,如 Arrow 文档中详述。然而,根据我的经验,这些可能会导致进一步的 DataType 问题,特别是对于复杂的 Postgres 模式。这会造成很大的维护负担。因此,我发现使用 DuckDB 的本机功能来执行这些转换任务可以防止此类复杂情况,并推荐它作为更直接、更可靠的解决方案。
参考: