You are setting a row tracer here:
> connection.setrowtrace(row_factory)
And also set a cursor factory here.
> registrar = apsw.ext.TypesConverterCursorFactory()
> connection.cursor_factory = registrar
The way the TypesConverterCursorFactory works is by registering a row tracer for its cursors which will take precedence over the connection one. You can see that code here (line 246 is what causes the tuple).
https://github.com/rogerbinns/apsw/blob/master/apsw/ext.py#L237
If you wanted a dict, you'd need to copy/inherit from that code and do what you want there.
The good news is that the next APSW release is going to make this way easier. I'm developing the code and especially the test suite right now. It works with SQLite's JSON support -
https://sqlite.org/json1.html
In particular SQLite has a binary JSON format which avoids having to parse JSON strings repeatedly, and APSW has code to automatically detect that format (JSONB).
You would write a converter where for example a datetime could be represented like this:
{ "$type": "datetime", "$value": "1757088099.227378" }
You will be able to register a converter that is called when bindings include a non-supported SQLite value. (The converter can be registered against apsw, the connection, or the cursor.)
See the default parameter of json.dumps:
https://docs.python.org/3/library/json.html#json.dump
You can either call the json module with your default converter which will produce a JSON text representation like above. Or your can call apsw's jsonb converter with the exact same default converter which will produce a SQLite JSONB blob. Either gets saved to the database.
Now see the object_hook parameter of json.loads:
https://docs.python.org/3/library/json.html#json.load
You would want an object hook that recognises the $type dict like above and convert it back to a datetime.
You will be able to register a converter for values coming back out of SQLite that are valid JSONB (blobs) and provide an object_hook. I am not currently intending to auto-recognise JSON (text) since that is a lot trickier.
The upshot of this is that it should be a lot easier using JSON to represent values, and conversion into and out of JSONB will be automagic. It will also free up the row factory so that you can get your dicts instead of tuples :)
There will be an example doc page for JSON which will use datetime as demonstration.
What do you think?
Roger