feat: add SQLite database backend for local/self-hosted deployments#75
Draft
xingyaoww wants to merge 1 commit into
Draft
feat: add SQLite database backend for local/self-hosted deployments#75xingyaoww wants to merge 1 commit into
xingyaoww wants to merge 1 commit into
Conversation
Add SQLite support via aiosqlite as an alternative to PostgreSQL, enabling open-source users to run the automation service without requiring a PostgreSQL instance. Changes: - config.py: Add db_url setting and is_sqlite property - db.py: Support SQLite engine creation with WAL mode and FK enforcement - models.py: Replace PostgreSQL-specific JSONB with cross-database JSON type - scheduler.py: Skip FOR UPDATE SKIP LOCKED on SQLite (not supported/needed) - dispatcher.py: Same FOR UPDATE SKIP LOCKED handling for SQLite - app.py: Auto-create tables for SQLite (skips Alembic PG-specific migrations) - migrations/env.py: Support SQLite with render_as_batch and skip advisory locks - pyproject.toml: Add aiosqlite dependency - tests/test_sqlite_backend.py: Comprehensive tests for SQLite backend Usage: Set AUTOMATION_DB_URL=sqlite+aiosqlite:///./automations.db Closes #62 (database support aspect) Co-authored-by: openhands <openhands@all-hands.dev>
|
🚀 Deploy Preview PR Created/Updated A deploy preview has been created/updated for this PR. Deploy PR: https://github.com/OpenHands/deploy/pull/3960 Once the deploy PR's CI passes, the automation service will be deployed to the feature environment. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds SQLite support via
aiosqliteas an alternative to PostgreSQL, addressing the database aspect of #62. This enables open-source users to run the automation service locally without requiring a PostgreSQL instance.Closes #62 (database support aspect)
Changes
Configuration (
automation/config.py)db_urlsetting (AUTOMATION_DB_URL) — a full database URL that takes precedence over individualdb_host/db_port/etc. settingsis_sqliteproperty for clean dialect detection throughout the codebasesqlite+aiosqlite:///andpostgresql+asyncpg://URLsDatabase Engine (
automation/db.py)_create_sqlite_engine()— creates an async SQLite engine via aiosqlite_create_pg_engine()for clarity_create_sqlite_engine, GCP instance →_create_gcp_engine, otherwise →_create_pg_engineModels (
automation/models.py)JSONB(PostgreSQL-specific) with genericJSONtype from SQLAlchemyJSONto the nativejson/jsonbtype automatically) while enabling SQLite compatibilitypostgresql_wherein partial indexes is silently ignored on non-PostgreSQL dialectsScheduler & Dispatcher (
automation/scheduler.py,automation/dispatcher.py)_is_sqlite()helper to detect the bound engine dialectFOR UPDATE SKIP LOCKEDon SQLite (SQLite uses database-level locking, not row-level locks)App Startup (
automation/app.py)Base.metadata.create_all()during startupJSONB,UUID,pg_advisory_lock)Alembic Migrations (
migrations/env.py)sqlite+aiosqliteURLs to syncsqlitefor Alembic (which runs synchronously)render_as_batch=Truefor SQLite (required for ALTER TABLE operations)Dependencies (
pyproject.toml)aiosqlite>=0.20to project dependenciesUsage
Testing
Added 14 new tests in
tests/test_sqlite_backend.py:TestSQLiteConfigis_sqliteproperty with various URL typesTestSQLiteEngineTestSQLiteModelsTestSQLiteSchedulerFOR UPDATE SKIP LOCKEDTestSQLiteDispatcherFOR UPDATE SKIP LOCKEDAll existing tests continue to pass unchanged.
Design Decisions
Generic
JSONoverJSONB: SQLAlchemy'sJSONtype maps to PostgreSQL's native JSON type automatically, so this is a no-op change for PostgreSQL deployments while enabling SQLite.Auto-create tables for SQLite: Rather than making all existing Alembic migrations dialect-aware (they use
JSONB,UUIDfromsqlalchemy.dialects.postgresql), SQLite deployments create tables directly from model definitions. This is appropriate because SQLite is for fresh local deployments, not migrating existing PostgreSQL data.Skip
FOR UPDATE SKIP LOCKEDon SQLite: SQLite only supports database-level locking. For single-process deployments (the target for SQLite), this is safe. The poll_threshold logic in the scheduler still provides fair rotation.WAL mode: Enabled on every SQLite connection for better concurrent read performance and to reduce lock contention.
This PR was created by an AI agent (OpenHands) on behalf of the user.
@xingyaoww can click here to continue refining the PR