๐ https://pypi.org/project/sqlalchemy-firebird/
pip install --upgrade sqlalchemy-firebirdIf you work with Firebird and SQLAlchemy, this one is worth your attention. It focuses on two things: fixing the bugs that actually hurt real applications, and shedding a decade of legacy baggage so the project is faster and safer to evolve from here on.
sqlalchemy-firebird had accumulated years of conditional code to support old Python versions, the legacy fdb driver, and Firebird 2.5 โ all at the same time. That made every fix risky and every feature slow to land.
2.2.0 draws a clear line: SQLAlchemy 2.0+, Firebird 3.0+, and the modern firebird-driver. With the old branches gone, the remaining code is small enough to read, reason about, and test properly โ and thatโs exactly what made the fixes below possible.
Reading BLOB columns through SQLAlchemy used to fail with errors like Can't read line from binary BLOB, or hand back already-closed reader objects. The dialect now materializes BLOBs as real bytes/str on every cursor it manages, so your result rows just contain the data โ no surprises, no closed streams. (Fixes #76 and #58.)
๐ข Auto-increment keys respect your column typeIdentity primary keys were always emitted as INTEGER. Now the dialect uses the columnโs actual compiled type, so a BigInteger primary key becomes a BIGINT ... GENERATED BY DEFAULT AS IDENTITY and a SmallInteger becomes SMALLINT. (Fixes #88.)
๐ Multiple Firebird servers on the same hostConnecting to two Firebird servers on the same host but different ports used to clobber each otherโs configuration. Server registrations are now keyed by host/port, so concurrent connections to different instances stay isolated. (Fixes #69.)
๐งฎ Reworked type systemThe numeric and string types (FLOAT, DOUBLE PRECISION, DECFLOAT, DECIMAL, CHAR/VARCHAR/NCHAR/NVARCHAR, and the binary variants) were rebuilt on top of the proper SQLAlchemy type hierarchy. This fixes a range of reflection and rendering glitches and removes a fragile dependency on a private SQLAlchemy internal method.
๐ฆ Firebird 3 / 4 / 5 correctnessDomain reflection (ReflectedDomain) and several Firebird 3-specific behaviors were fixed so the dialect behaves consistently across all currently supported Firebird versions.
A healthy codebase is as much about what you remove as what you add. To keep the project maintainable, 2.2.0 drops the following legacy support:
If youโre still on Firebird 2.5 or the fdb driver, stay on the 2.1 line for now. For everyone on a modern stack, dropping these branches is what unblocked the fixes above โ and what will keep new fixes coming faster.
Reliability isnโt a promise, itโs a test matrix. Every change in 2.2.0 is validated in CI against the full grid of supported versions:
Firebird 3.0 Firebird 4.0 Firebird 5.0 Python 3.11 โ โ โ Python 3.12 โ โ โ Python 3.13 โ โ โThe whole toolchain was modernized too โ uv for reproducible, locked dependencies, ruff for linting/formatting, automated Firebird provisioning in CI, and OIDC Trusted Publishing to PyPI (no stored tokens).
This is where you come in. The dialect now covers a lot of ground, but nothing beats real-world usage:
If something doesnโt behave the way you expect โ or works great and you want to say so โ please open an issue:
๐ https://github.com/fdcastel/sqlalchemy-firebird/issues
Bug reports with a small reproducible example are pure gold and help the next fix land faster.
A big thank-you to Paul Graves-DesLauriers, who created and maintained sqlalchemy-firebird for years and laid the foundation this release builds on โ and to everyone in the Firebird community who has filed issues, sent reproductions, and tested along the way. This project moves forward because you keep poking at it.
Thanks for using sqlalchemy-firebird, and happy querying! ๐ฅ