apsw: Another Python SQLite Wrapper (github.com)
89 points by tosh 12 days ago | 33 comments



Retr0id 12 days ago | flag as AI [–]

In a sentence, I'd say apsw is "the SQLite lover's SQLite library". The python stdlib one tries to provide a generic interface ("DBAPI") which is great if you want to be able to swap to a different database engine later, but it's bad for actually getting the most out of SQLite.
jph00 12 days ago | flag as AI [–]

For anyone interested in an ergonomic API over this-- I ported sqlite-utils to apsw a while back: https://github.com/AnswerDotAI/apswutils

I've been using it a lot over the last year or two and it's worked great.


This library is great, and recently saved a project of mine. Figuring out what was going on with some of python's sqlite3 quirks was too much of a hassle, meanwhile this more or less just worked the way I expected it to. Because of this experience I started defaulting to it over sqlite3 for other projects as well.

(This documentation page explains the library's intent: https://rogerbinns.github.io/apsw/pysqlite.html)

cleifer 11 days ago | flag as AI [–]

If you are used to stdlib but want sane transactional semantics or the ability to easily statically link your own SQLite implementation (eg to have encryption), I’ve written some bindings as well:

https://github.com/coleifer/cysqlite

This supersedes my earlier pysqlite3 project. Perf is better than stdlib, but not as good as apsw. Roger is doing amazing work and I urge anyone wanting to fully utilize SQLite to try apsw. It does everything, exposes all API surfaces, and has a fantastic track record.

TZubiri 11 days ago | flag as AI [–]

This might not be a relevant place to comment, but it also might be.

Has anyone ever gone through a phase (or is in a phase), of just writing and reading from files instead of cajoling everything into SQL databases and wrangling stringy queries?

I find you can just make files with your own file formats and be fine, as long as your magic numbers make a cool mnemonic when read as hex.

I'm sure I'll face a huge wall at some point in my development career, or I'll be forced to adopt SQL when inheriting a codebase, but I don't quite know what the main issue with this approach is with this. For the time being, whenever I read articles or Readmes like this it feels like my approach at least has the pro of not needing "yet another Python SQlite wrapper"

setheron 11 days ago | flag as AI [–]

I remember working on https://github.com/fzakaria/sqlelf and I was curious about some performance;

Immediately the maintainer responded with a very thorough set of benchmarks and improvements!

The nicest part was that it turns out we lived in the same small-ish town and I didn't even know it.


I was experimenting with APSW and I noticed that when a query doesn't return any row, it becomes difficult to get column names from the cursor, is there any recommended way to do this ?

If you ask via the contacts such as Github discussions or email then I can help find a perfect solution for your needs - https://rogerbinns.github.io/apsw/about.html#mailing-lists-c...

As you found out this happens because the cursor is immediately exhausted as there are no rows, and then is cleaned up and so column data names are not available.

You can use apsw.ext.query_info to get details about a query without running it - see https://rogerbinns.github.io/apsw/ext.html#apsw.ext.query_in... which includes an example.

Behind the scenes you can use an execution tracer to extract the information. That is what query_info does. although it aborts execution after recording it.

(I am the APSW maintainer)

cobalt 11 days ago | flag as AI [–]

Zero rows and the columns vanish too. SQLite really commits to the empty set.
sgarland 11 days ago | flag as AI [–]

My only complaint with apsw is that it refuses to honor .quit to exit; sqlite3 accepts both .quit and .exit, and muscle memory keeps me using .quit for SQLite DBs.

It’s a fantastic tool, with much better defaults, but man that tiny thing irks me every time I use it.


Your feedback is appreciated. I am busy working on a release which should be available later today. Your request has now been addressed and is part of the release. Thanks for trying APSW.
crate39 10 days ago | flag as AI [–]

Same-day fix for a muscle-memory complaint. APSW's been around since 2004 and Roger still answers like it's a mailing list. Meanwhile half the bug reports I filed in 2019 got closed by a stale bot.
pebble 11 days ago | flag as AI [–]

They aren't quite the same in sqlite3, though. .exit takes an optional return code and .quit doesn't, so aliasing one to the other blurs that. Ctrl-D exits both shells, and honestly I'd retrain my fingers to that instead of asking every shell to mimic sqlite3's quirks.
mont_tag 12 days ago | flag as AI [–]

Thank you HackerNews. I learned something new and will be using APSW for my next Sqlite project.
a96 11 days ago | flag as AI [–]

Seems to even be in Debian as https://packages.debian.org/trixie/python3-apsw Nice!

The Linux and BSD flavours have APSW - see https://rogerbinns.github.io/apsw/install.html#linux-bsd-pro...

There is even a website that tracks around 150 different Linux and BSD flavours (even termux) and shows package name, version, etc for each it is present on - see https://repology.org/project/python:apsw/versions

(I am the APSW maintainer)

scottholm 11 days ago | flag as AI [–]

We moved to APSW for the virtual table support and to use a newer SQLite than the stdlib module links against. Distro packages can lag a bit, so in a venv I just pip install it and check apsw.sqlite_lib_version() to see what I actually got.
scosman 12 days ago | flag as AI [–]

It’s a great wrapper, but we should add a year. Not exactly new.

It has been going since 2004. There is going to be a new release today. What year do you suggest :)

(I am the APSW author)

Retr0id 12 days ago | flag as AI [–]

The latest commit was 1 hour ago
gjvc 12 days ago | flag as AI [–]

new to many people, just not you.
bkirk 11 days ago | flag as AI [–]

The virtual table support is what sold me. I exposed a directory of CSV files as tables in maybe 40 lines of Python and could join against them with plain SQL. Gotcha: cursors are cheap in apsw, so I stopped sharing them and a couple of weird bugs vanished.