What happened?
When writing an Ibis expression that contains a geospatial:geometry column to DuckDB, both:
con.create_table("name", expr, overwrite=True)
con.insert("name", expr)
fail with:
Conversion Error: Unimplemented type for cast (BLOB -> GEOMETRY)
This appears to come from generated SQL that applies ST_ASWKB("geometry"), producing a BLOB that DuckDB then tries to cast into a GEOMETRY column.
What did you expect to happen?
I expected both create_table and insert to write geospatial columns directly (or round-trip them safely) without requiring manual SQL workarounds.
reproducible example:
import ibis
import duckdb
print("ibis", ibis.__version__)
print("duckdb", duckdb.__version__)
con = ibis.duckdb.connect(extensions=["spatial"])
expr = con.sql("""
SELECT
1::INTEGER AS id,
ST_Point(1.0, 2.0) AS geometry
""")
print("expr schema:", expr.schema())
# expr schema includes: geometry geospatial:geometry
# 1) Fails
con.create_table("tmp_geospatial_from_sql", expr, overwrite=True)
# 2) Also fails
con.create_table("tmp_insert_target", schema=expr.schema(), overwrite=True)
con.insert("tmp_insert_target", expr)
What version of ibis are you using?
ibis 12.0.0
What backend(s) are you using, if any?
duckdb 1.5.1 with spatial extension enabled
Relevant log output
raceback from con.create_table(...):
Traceback (most recent call last):
File "<stdin>", line 19, in <module>
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\duckdb_init_.py", line 236, in create_table
cur.execute(insert_stmt).fetchall()
~~~~~~~~~~~^^^^^^^^^^^^^
_duckdb.ConversionException: Conversion Error: Unimplemented type for cast (BLOB -> GEOMETRY) when casting from source column geometry
LINE 1: ...szpfbqbbxlc6wacexioe" ("id", "geometry") SELECT * REPLACE (ST_ASWKB("geometry") AS "geometry") FROM (SELECT CAST(1...
^
Traceback from con.insert(...):
Traceback (most recent call last):
File "<stdin>", line 20, in <module>
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\sql_init_.py", line 463, in insert
with self.safe_raw_sql(query):
~~~~~~~~~~~~~~~~~~^^^^^^^
File "C:\Users\sameer\AppData\Roaming\uv\python\cpython-3.13.2-windows-x86_64-none\Lib\contextlib.py", line 141, in enter
return next(self.gen)
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\duckdb_init.py", line 348, in safe_raw_sql
yield self.raw_sql(*args, **kwargs)
~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
File "C:\Users\sameer\Projects\mint_geocoding.venv\Lib\site-packages\ibis\backends\duckdb_init.py", line 116, in raw_sql
return self.con.execute(query, **kwargs)
~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^
_duckdb.ConversionException: Conversion Error: Unimplemented type for cast (BLOB -> GEOMETRY) when casting from source column geometry
LINE 1: ... INTO "tmp_insert_target" ("id", "geometry") SELECT * REPLACE (ST_ASWKB("geometry") AS "geometry") FROM (SELECT CAST(1...
Code of Conduct
What happened?
When writing an Ibis expression that contains a geospatial:geometry column to DuckDB, both:
con.create_table("name", expr, overwrite=True)
con.insert("name", expr)
fail with:
Conversion Error: Unimplemented type for cast (BLOB -> GEOMETRY)
This appears to come from generated SQL that applies ST_ASWKB("geometry"), producing a BLOB that DuckDB then tries to cast into a GEOMETRY column.
What did you expect to happen?
I expected both create_table and insert to write geospatial columns directly (or round-trip them safely) without requiring manual SQL workarounds.
reproducible example:
What version of ibis are you using?
ibis 12.0.0
What backend(s) are you using, if any?
duckdb 1.5.1 with spatial extension enabled
Relevant log output
Code of Conduct