{"id":3447,"library":"databases","title":"Asynchronous Database Toolkit","description":"The `databases` library provides asynchronous database support for Python, designed to work with `asyncio` and `await`. It supports PostgreSQL, MySQL, and SQLite, and integrates well with SQLAlchemy Core expression language. The current version is 0.9.0, and it has an active development cadence with regular updates.","status":"active","version":"0.9.0","language":"en","source_language":"en","source_url":"https://github.com/encode/databases","tags":["async","database","sql","sqlalchemy","asyncio","orm"],"install":[{"cmd":"pip install databases","lang":"bash","label":"Base installation"},{"cmd":"pip install databases[postgresql]","lang":"bash","label":"With PostgreSQL driver (asyncpg)"},{"cmd":"pip install databases[mysql]","lang":"bash","label":"With MySQL driver (aiomysql)"},{"cmd":"pip install databases[sqlite]","lang":"bash","label":"With SQLite driver (aiosqlite)"}],"dependencies":[{"reason":"Used for SQL expression language support, though raw SQL is also possible.","package":"sqlalchemy","optional":false},{"reason":"PostgreSQL database driver.","package":"asyncpg","optional":true},{"reason":"MySQL database driver. Alternatively, asyncmy can be used.","package":"aiomysql","optional":true},{"reason":"SQLite database driver.","package":"aiosqlite","optional":true}],"imports":[{"symbol":"Database","correct":"from databases import Database"},{"note":"Represents a single row from a database query result.","symbol":"Record","correct":"from databases import Record"}],"quickstart":{"code":"import asyncio\nimport os\nfrom databases import Database\n\nasync def main():\n    # Use an in-memory SQLite database for a simple example.\n    # For a real application, use a proper URL like DATABASE_URL = 'postgresql://user:pass@host/db'\n    database = Database(os.environ.get('DATABASE_URL', 'sqlite:///./test.db'))\n\n    try:\n        await database.connect()\n        print(\"Database connected.\")\n\n        # Create a table\n        query = \"\"\"\n            CREATE TABLE IF NOT EXISTS users (\n                id INTEGER PRIMARY KEY,\n                name VARCHAR(100)\n            );\n        \"\"\"\n        await database.execute(query=query)\n        print(\"Table 'users' created or already exists.\")\n\n        # Insert data\n        query = \"INSERT INTO users(name) VALUES (:name)\"\n        await database.execute(query=query, values={\"name\": \"Alice\"})\n        print(\"Inserted 'Alice'.\")\n\n        # Select data\n        query = \"SELECT id, name FROM users\"\n        rows = await database.fetch_all(query=query)\n        for row in rows:\n            print(f\"User: {row['id']}, {row['name']}\")\n\n    except Exception as e:\n        print(f\"An error occurred: {e}\")\n    finally:\n        await database.disconnect()\n        print(\"Database disconnected.\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n","lang":"python","description":"This quickstart demonstrates connecting to a database, executing a DDL statement to create a table, inserting a record, and fetching all records. It uses an in-memory SQLite database by default but can be configured with an environment variable for other databases. Remember to install the appropriate database driver (e.g., `pip install databases[sqlite]`)."},"warnings":[{"fix":"Ensure your project runs on Python 3.8 or higher. If using SQLAlchemy, consider upgrading to SQLAlchemy 2.x. If you must use older SQLAlchemy 1.x, consult `databases` documentation for specific version compatibility.","message":"Version 0.9.0 dropped support for Python 3.7 and earlier versions. Additionally, it now officially supports SQLAlchemy 2.x, which might introduce compatibility issues if you are still using older SQLAlchemy 1.x versions.","severity":"breaking","affected_versions":">=0.9.0"},{"fix":"Carefully review concurrent database operations in your application. Ensure that connections and transactions are explicitly managed or passed between tasks where shared behavior is intended, rather than relying on implicit inheritance.","message":"In version 0.8.0, connection and transaction isolation was significantly improved. Database connections are now task-local and not inherited by child tasks. The `@db.transaction` decorator uses the calling task's connection, and new tasks use new connections unless explicitly provided.","severity":"breaking","affected_versions":">=0.8.0"},{"fix":"Always install `databases` with the appropriate extras, e.g., `pip install databases[postgresql]`, or install the driver manually.","message":"You must install the specific database driver package for your chosen database alongside `databases`. For example, `pip install databases asyncpg` for PostgreSQL, `pip install databases aiomysql` for MySQL, or `pip install databases aiosqlite` for SQLite. Installing just `databases` is not sufficient for database connectivity.","severity":"gotcha","affected_versions":"all"},{"fix":"Always check the specific release notes for `databases` regarding SQLAlchemy compatibility. For `>=0.9.0`, it's highly recommended to use SQLAlchemy 2.x. If sticking with SQLAlchemy 1.x, careful version pinning of both `databases` and `SQLAlchemy` is required.","message":"Compatibility with SQLAlchemy 1.4.x has been a recurring issue across several `databases` versions, with specific pins and fixes (e.g., `0.6.2` pinned `<=1.4.41`, `0.7.0` supported `>=1.4.42,<1.5`). While `0.9.0` adds SQLAlchemy 2.x support, transitioning from older SQLAlchemy 1.x with `databases` can be complex.","severity":"gotcha","affected_versions":"0.6.0 - 0.9.0"}],"env_vars":null,"last_verified":"2026-04-11T00:00:00.000Z","next_check":"2026-07-10T00:00:00.000Z"}