Firebird Driver for Python
firebird-driver is the official Python Database API 2.0-compliant driver for the open-source relational database Firebird®. It provides a pure-Python interface built on top of the native Firebird client library, exposing both the standard DB API features and the new interface-based client API introduced in Firebird 3. The library is currently at version 2.0.2 and maintains an active release cadence with regular updates and bug fixes.
Common errors
-
AttributeError: object has no attribute 'logging_id' in "__del__" methods
cause This error typically occurs when using `firebird-driver` versions 2.0.1 or 2.0.2 with an older version of `firebird-base` (specifically, pre-2.0) where `LoggingIdMixin` was removed or changed, leading to incompatible attribute access.fixUpgrade `firebird-base` to version 2.0 or higher: `pip install --upgrade firebird-base`. -
Database error: ('Error loading Firebird client library "fbclient.dll"', -902, 335544721)cause The Firebird client library (`fbclient.dll` on Windows or `libfbclient.so` on Linux) could not be found or loaded by the Python driver. This means it's either not installed, or its location is not in the system's library search path.fixInstall the Firebird client tools for your OS. Ensure the directory containing `fbclient.dll` (Windows) or `libfbclient.so` (Linux) is added to your system's `PATH` or `LD_LIBRARY_PATH` environment variable, or configure the `fb_client_library` path directly via `firebird.driver.driver_config.set_client_library('/path/to/fbclient.dll')`. -
[ODBC Firebird Driver][Firebird]Attempt to reclose a closed cursor
cause While this specific message often relates to ODBC drivers, the underlying issue of attempting to close a cursor that is already closed can occur with `firebird-driver` due to its non-standard `Cursor.close()` behavior. If you call `close()` multiple times on the same cursor instance or attempt operations after it's logically 'closed' in your application logic, this can arise.fixReview your application's cursor management. Ensure that `cursor.close()` is called only once per logical cursor lifecycle. If you need to execute multiple statements sequentially, either reuse the cursor (knowing the `firebird-driver` allows it) or create new cursor instances explicitly for each independent operation or result set. -
Database error: ('Dynamic SQL Error\nSQL error code = -104\nToken unknown - line 1, column 7\nSELECT * FORM tablename', 335544569, 335544332)cause This is a generic Firebird SQL error (SQLCODE -104) indicating a syntax error in the SQL statement. The example provided shows 'FORM' instead of 'FROM'.fixCarefully review the SQL query for typos, incorrect keywords, missing punctuation, or other syntax mistakes. Consult Firebird SQL documentation if unsure about specific syntax elements.
Warnings
- breaking Version 2.0.0 introduced several breaking changes, including raising the minimal Python version to 3.11, removal of `LoggingIdMixin` usage (requiring `firebird-base v2.0+`), and the `database` parameter for `connect` and `create_database` now accepting `pathlib.Path` objects.
- gotcha The `firebird-driver` requires the native Firebird client library (`fbclient.dll` on Windows, `libfbclient.so` on Linux) to be installed on the system and accessible via the system's library path (e.g., `PATH` on Windows, `LD_LIBRARY_PATH` on Linux). The Python driver itself is a wrapper around this native library.
- gotcha The `Cursor.close()` method in `firebird-driver` deviates from the Python DB API 2.0 specification. It only releases resources associated with the executed statement (like the result set), but the cursor instance itself remains usable for executing new SQL commands. Relying on this behavior may make code less portable.
- breaking The `firebird-driver` is designed for Firebird 3.0 and newer. Attempting to connect to older Firebird server versions (e.g., Firebird 2.5) may result in compatibility issues or errors.
Install
-
pip install firebird-driver
Imports
- connect
import firebird.driver.core as fbd
from firebird.driver import connect
- fdb
import fdb
from firebird.driver import connect
Quickstart
import os
from firebird.driver import connect, DatabaseError
database_path = os.environ.get('FIREBIRD_DB_PATH', 'test.fdb')
user = os.environ.get('FIREBIRD_USER', 'sysdba')
password = os.environ.get('FIREBIRD_PASSWORD', 'masterkey')
# Ensure the Firebird client library is accessible (e.g., in PATH or LD_LIBRARY_PATH)
# You might need to set fb_client_library in driver_config for specific paths.
try:
# Connect to the Firebird database
# For a remote server, specify 'host' and 'port' in addition to 'database'
# E.g., con = connect('localhost:/path/to/my.fdb', user=user, password=password)
con = connect(database_path, user=user, password=password)
print("Successfully connected to Firebird database!")
# Create a Cursor object
cur = con.cursor()
# Example: Create a table
try:
cur.execute("CREATE TABLE languages (name VARCHAR(20), year_released INTEGER)")
print("Table 'languages' created.")
except DatabaseError as e:
if 'Table or view already exists' in str(e): # Specific error for existing table
print("Table 'languages' already exists.")
else:
raise # Re-raise other database errors
# Example: Insert data
cur.execute("INSERT INTO languages (name, year_released) VALUES (?, ?)", ('Python', 1991))
cur.execute("INSERT INTO languages (name, year_released) VALUES (?, ?)", ('C', 1972))
con.commit()
print(f"{cur.rowcount} rows inserted.")
# Example: Query data
cur.execute("SELECT name, year_released FROM languages ORDER BY year_released")
print("\n--- Languages ---")
for row in cur.fetchall():
print(f"Name: {row[0]}, Released: {row[1]}")
cur.close()
con.close()
print("Connection closed.")
except DatabaseError as e:
print(f"Database error: {e}")
print("Ensure Firebird server is running and the client library is configured correctly.")
except Exception as e:
print(f"An unexpected error occurred: {e}")