Replies: 1 comment
|
As far as the current public Python API goes, you are not missing a method: The relation necessarily retains connection context internally, which is why cross-connection combinations can be rejected, but that context is not surfaced through the Python binding. A library also cannot safely create the per-thread cursor recommended by the threading guide from the relation alone. Given that, the safe choices today are:
Trying a join merely to discover identity and catching the error is possible but is not a good predicate: it does real binding work and couples the library to an error string. Reaching into pybind internals would be even less stable. A narrow public API such as |
Uh oh!
There was an error while loading. Please reload this page.
Hi there 👋🏼 I am a Narwhals maintainer; Narwhals is a compatibility layer that lets library authors write dataframe-agnostic code, DuckDB included. I have been working on thread-safety and hit the same wall twice, so I'd like to ask whether we're missing an API.
What I am trying to achieve
Given only a
DuckDBPyRelation, handed in by the user, I'd like to be able to:.cursor()on it; andAs far as we can tell neither is possible today: nothing on a
DuckDBPyRelationrefers to its connection.Why I would like to achieve it
.cursor()on the connection. When all we hold is a relation there's nothing to call.cursor()on. Concretely: reporting the schema of aTIMESTAMPTZcolumn requires the connection'sTimeZonesetting, which we read withrel.query(...). That executes on the relation's connection, so two threads inspecting schemas of relations from one connection collide withInvalidInputException: Attempting to execute an unsuccessful or closed pending query result. We currently serialize that single query behind a module-level lock. A per-relation cursor would be the correct fix, and would also stop us serializing work on connections that have nothing to do with each other.join,unionandcrossall raiseCannot combine LEFT and RIGHT relations of different connections!. Our API takes two user frames and joins them internally, so that error surfaces from deep inside our call stack with no hint that the cause is which connection each frame came from. If we could compare the two relations' connections, or just a stable identity for them, we could raise a clear library-level error up front, pointing at the actual fix.We don't have a clear workaround for this just yet.
Questions
DuckDBPyRelation.connectionbe considered?rel_a.same_connection_as(rel_b), purely so libraries can raise a better error?Happy to open issues or (try to) contribute a PR if any of these are wanted.
Related: #40
All reactions