Hi all, it seems DuckDB can support composite types as in Redirecting…
I want to know how to insert into columns with one of these types from a DataFrame. I’ve tried the Appender API and directly using prepared statements, none of which seems to work. Can someone help me? A MWE is below:
using DuckDB, DataFrames
function load_table!(db::T, df::DataFrame, name) where {T<:DuckDB.DB}
sch = DataFrame(DBInterface.execute(db, "DESCRIBE $(name);"))
sch_cols = sch[!, :column_name]
@assert Set(names(df)) == Set(sch_cols)
appender = DuckDB.Appender(db, name)
for i in eachrow(df)
for j in sch_cols
# database columns are ordered
DuckDB.append(appender, i[j])
end
DuckDB.end_row(appender)
end
DuckDB.flush(appender)
DuckDB.close(appender)
end
db_mem = DBInterface.connect(DuckDB.DB, ":memory:")
DBInterface.execute(db_mem, "CREATE TABLE tab1 (id INTEGER PRIMARY KEY, vals INTEGER[]);")
tab1_df = DataFrame(id=1:10, vals=fill([1,2,3],10))
load_table!(db_mem, tab1_df, "tab1") # errors
stmt = DBInterface.prepare(db_mem, "INSERT INTO tab1 VALUES(:id, :vals)")
DBInterface.executemany(stmt, (id=tab1_df.id, vals=tab1_df.vals)) # errors
stmt = DBInterface.prepare(db_mem, "INSERT INTO tab1 VALUES(?, ?)")
DBInterface.executemany(stmt, (id=tab1_df.id, vals=tab1_df.vals)) # errors
# flatten the df
tab1_df = DataFrame(id=1:10, vals=fill([1,2,3],10))
flat_df = flatten(tab1_df, [:vals])
# register the data frame or create the table in whatever way
DuckDB.register_data_frame(db_mem, flat_df, "flat_tab1")
# create aggregated table
DuckDB.query(
db_mem,
"CREATE OR REPLACE TABLE tab1 AS
SELECT
id,
ARRAY_AGG(vals) AS vals,
FROM flat_tab1
GROUP BY
id",
)
# trust buy verify
DuckDB.query(db_mem, "FROM tab1") |> DataFrame
Please let me know if this is helpful.
PS. If you can add the errors you’re having, it will help more people find this issue (especially in the future)