Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Db Sqlite Laravel Package

yiisoft/db-sqlite

SQLite driver for the Yii Database library, providing connection handling, schema introspection, query building, and ActiveRecord support for SQLite-backed Yii applications.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

  • The package is yiisoft/db-sqlite 2.0.0 — the SQLite driver for the Yii3 database abstraction (yiisoft/db), not a Laravel/Eloquent driver. It does not integrate with Illuminate\Database, Laravel's query builder, Eloquent, migrations, or DB:: facades.
  • It is a PSR-oriented, framework-agnostic layer (PSR-3 logger, PSR-16 cache, PSR-17 HTTP factory for DSN/data sources) built around interfaces: ConnectionInterface, SchemaInterface, CommandInterface, QueryBuilder, ColumnInterface, ColumnBuilder, ColumnFactory, ColumnDefinitionBuilder, SqlParser, QuoterInterface.
  • As a result, adopting it inside an existing Laravel application implies running a second DBAL alongside Eloquent for a narrow slice of functionality (typically a reporting/read-only SQLite path, a sharded analytics store, or a legacy Yii component being carried forward), not replacing Laravel's driver.
  • Best architectural fit: Laravel apps that must interoperate with a legacy Yii/Yii3 codebase or that consume Yii packages as isolated libraries; greenfield Laravel work would not choose this over Illuminate\Database + sqlite3/PDO.
  • The 2.0 line is a genuine internal restructure: column handling is now split across ColumnFactory, ColumnBuilder, ColumnDefinitionBuilder, and typed ColumnSchemaInterface implementations (cast-per-datatype for performance). This is a cleaner design, but it is a substantially different extension surface from 1.x.

Integration feasibility

  • Composer install works, but 2.0 requires a matching 2.x yiisoft/db and PHP 8.1–8.5. Laravel 10/11 ships ^8.1/^8.2, so PHP is generally compatible; the constraint that bites is the paired yiisoft/db major and its transitive PSR expectations.
  • Laravel already binds PSR-3 (Log) and PSR-16 (Cache) adapters, but does not ship a PSR-17 HTTP factory by default — a nyholm/psr7 (or equivalent) binding is likely required in AppServiceProvider. Verify against yiisoft/db's data-source/DSN construction path after the Dsn refactor (#323, #373).
  • The driver has no Laravel service provider, no config file, and no facade. Expect a custom singleton binding wiring Connection with logger, cache, and HTTP factory, plus manual lifecycle handling (no DB::transaction() integration; use ConnectionInterface::createTransaction(), now more specifically typed per #324).
  • Connection pooling is not applicable for SQLite; concurrency is governed by file-level locking. Laravel's queue workers and Octane will each hold their own Connection instance — need explicit singleton scoping and a post-fork/reload strategy.
  • Feasibility verdict: technically possible, organizationally awkward. The integration cost is dominated by two-cultures plumbing (two DB abstractions, two migration systems, two transaction models), not by the package's own complexity.

Technical risk

  • Breaking changes are extensive. This is a major release with removals and signature changes that will break any 1.x consumer:
    • TableSchema class removed; Schema refactored (#377), loadResultColumn() added (#348).
    • ColumnInterface originally removed (#332) then ColumnSchemaInterface renamed to ColumnInterface (#334) — any custom column classes must be re-based on the new typed hierarchy (DateTimeColumn, enum column support #404, collation #380).
    • QueryBuilder constructor changed (#330); expression namespaces relocated per yiisoft/db (#391); hasLimit()/hasOffset() usage removed (#342).
    • Command::insertWithReturningPks() now returns array|false (#339) — a falsy return can silently mask a failed insert if callers only check truthiness.
    • Quote character changed from backtick to double quote (#362). Any hand-written SQL, view definitions, stored snippets, or snapshot tests containing backticks will break. This is the highest-probability silent regression in a Laravel context, where raw SQL fragments are common.
    • unsigned column usage now throws (#402) rather than being tolerated — schema definitions ported from MySQL-flavored migrations may fail at runtime.
    • Removed yiisoft/json dependency (#343); JsonExpressionBuilder and JSON tests moved to yiisoft/db (#337) — JSON behavior is now owned upstream, so version-pinning must move in lockstep.
    • Schema::getCacheKey()/getCacheTag() removed (#347) — any schema-caching integration built on those hooks must be rebuilt.
    • Exception type changes (#364) mean existing catch blocks targeting Yiisoft\Db\Exception\InvalidArgumentException will no longer match.
  • Upgrade blast radius is cross-package. yiisoft/db, yiisoft/db-sqlite, and any active record/ORM layer above them must move together. There is no partial-upgrade path.
  • Ecosystem maturity risk. Yii3 is pre-1.0 in many components; a 2.0 driver release with this many intra-major churns signals the API is still settling. Budget for a repeat of this exercise on the next yiisoft/db major.
  • New surface area to validate. upsertReturning() (#356/#357), insertReturningPks() (#360/#361), FOR clause (#354), JSON OVERLAPS (#310/#393), caseSensitive LIKE option (#344), and ArrayMerge/Greatest/Least builders (#384/#390) are welcome capabilities but expand the test matrix — particularly FOR UPDATE, which SQLite does not truly support and whose behavior should be characterized before relying on it.
  • Overall technical risk: high for anyone on 1.x, moderate for new adoption, low for the package's own correctness given the test coverage implied by the refactor volume.

Key questions

  1. What is the actual reason to introduce this package — legacy Yii interop, a specific SQLite capability Laravel's driver lacks, or an inherited dependency? If the answer is "SQLite access," Laravel's native driver is the correct choice and this evaluation should terminate.
  2. Will this run alongside Eloquent on the same SQLite file, or against a separate database? Concurrent writers on one SQLite file from two DBALs is a locking and transaction-isolation hazard.
  3. Is there any 1.x code in the estate? If so, who owns the port, and has the backtick→double-quote change been traced through all raw SQL and fixtures?
  4. Which yiisoft/db version does 2.0.0 require, and is that constraint satisfiable alongside the rest of the Composer graph (notably PSR-7/17 implementations and any existing yiisoft/json consumers)?
  5. Who on the team can debug Yii3 DBAL internals at 2 a.m.? If the answer is "no one," the bus factor is the dominant risk, not the code.
  6. Does the product requirement actually need the new 2.0 capabilities (returning-clause upserts, JSON overlaps, enum columns, collation), or is the upgrade being driven purely by a transitive constraint?

Integration Approach

Stack fit

  • Laravel 10/11 + PHP 8.2/8.3 is compatible in principle; PHP 8.1 is the floor and 8.5 is claimed support — do not adopt the 8.5 claim without verifying your runtime image, since 8.5 is a very recent target.
  • Two viable shapes:
    1. Sidecar DBAL — bind Yiisoft\Db\Sqlite\Connection as a singleton for a scoped set of jobs/services; Eloquent remains the system of record. Lowest blast radius, highest conceptual overhead.
    2. Legacy bridge — a Yii component is being lifted into a Laravel app; this package comes along as a transitive dependency and is wrapped behind an app-owned repository interface.
  • Do not attempt to make this the primary data layer in a Laravel app. You would forfeit migrations, model events, factories, seeding, RefreshDatabase, and Telescope/query-log integration for no compensating benefit.
  • Recommended posture: adapter/wrapper. Define an app-owned interface (SqliteReportRepository, LegacyLedgerReader) and keep every Yiisoft\Db\* type behind it. This contains the next major-version churn to a single directory.

Migration path

  • No 1.x → 2.0 migration is required if this is a first adoption, which is the favorable case. If 1.x is present, treat it as a rewrite:
    1. Pin yiisoft/db and yiisoft/db-sqlite to compatible 2.x majors in one commit; expect the resolver to reject intermediate combinations.
    2. Grep the entire codebase and fixture set for backticks, getRawTableName, getCacheKey, getCacheTag, ColumnSchemaInterface, TableSchema, hasLimit, hasOffset, unsigned, and Yiisoft\Db\Exception\InvalidArgumentException.
    3. Re-base custom column classes onto the new typed ColumnSchemaInterface hierarchy and route SQL generation through ColumnDefinitionBuilder.
    4. Update QueryBuilder construction sites for the new constructor signature.
    5. Audit every insertWithReturningPks() caller for the new array|false contract.
    6. Refresh schema-cache strategy now that the cache key/tag hooks are gone.
  • For a first adoption, use a strangler pattern: one read-only use case, behind a feature flag, against a copy of the data, before any production traffic.

Compatibility

  • Hard requirements: PHP ^8.1, matching yiisoft/db 2.x, a PSR-17 HTTP factory (nyholm/psr7 recommended for Laravel), PSR-3 logger and PSR-16 cache (both already available via Laravel adapters).
  • The yiisoft/db-implementation virtual package (#368) means Composer will permit only one concrete driver implementation per install — verify this does not conflict with any other Yii DB driver already in the graph.
  • SQLite-specific caveats: no true unsigned (now throws, per #402), FOR UPDATE has no meaningful semantics, and returning-clause support depends on the bundled SQLite version (3.35+ for RETURNING). Confirm the runtime libsqlite3 version in your container images, not just locally.
  • Laravel's SQLite connection and this package's connection are independent; they will not share prepared-statement caches, transaction state, or schema metadata. Treat the schema as owned by exactly one of them.
  • PHP 8.4/8.5 compatibility is asserted, not proven for your dependency set — validate on the actual runtime, since deprecation noise from either DBAL can be significant.

Sequencing

  1. Week 1 — Decision gate. Confirm there is no Laravel-native alternative that satisfies the requirement. Document the justification. If the requirement is plain SQLite access, stop.
  2. Week 1 — Constraint spike. Resolve the Composer graph in a throwaway branch: yiisoft/db-sqlite 2.x + yiisoft/db 2.x + PSR-17 factory + existing Laravel deps. A failed resolution here is the cheapest possible failure.
  3. Week 2 — Container wiring. Service provider, singleton Connection, PSR-17 binding, logger/cache adapters, DSN construction post-Dsn refactor, configuration in config/database.php (custom key, not the connections array).
  4. Week 2–3 — Adapter layer. App-owned repository interfaces + implementations, plus characterization tests for the capabilities you actually intend to use (upsertReturning, caseSensitive LIKE, JSON overlaps, enum columns).
  5. Week 3 — Concurrency and failure testing. Multi-process write tests on the SQLite file, transaction rollback behavior, Octane/queue-worker lifecycle, array|false return handling.
  6. Week 4 — Shadow read in staging behind a flag, then a limited production read path, before widening scope.
  7. Ongoing — Pin and freeze. Lock exact 2.x versions, enable Dependabot with a manual-merge policy for this subtree, and schedule a review on any yiisoft/db 3.0 signal.

Operational Impact

Maintenance

  • Two DBALs, two maintenance streams. Schema changes must be reflected in Laravel migrations and in whatever the Yii connection expects; there is no shared source of truth. This is the single largest ongoing tax and it accrues on every schema change, forever, until the bridge is removed.
  • The 2.0 release itself demonstrates the maintenance profile: ~70 issues across removals, renames, and refactors, including a rename-then-rename-back sequence on ColumnInterface (#332/#334). Expect another exercise of this size at the next major.
  • Pin exact versions. Yii3 packages move quickly and a minor release in this ecosystem has historically carried behavior changes that would be minor-version-inappropriate elsewhere.
  • Version-locking yiisoft/db, yiisoft/db-sqlite, and any ORM layer together means a single Dependabot PR becomes a coordinated upgrade — plan for it rather than being surprised by it.

Support

  • Bus factor is the headline operational risk. Knowledge of Yii3's DBAL internals is rare in a Laravel shop. Identify or hire one person who can read the yiisoft/db source, and document the wiring decisions in an ADR.
  • Upstream support is community-driven via GitHub issues; there is no commercial SLA. Response times on the referenced issue numbers suggest an active but small maintainer group (notably @Tigrov, @vjik).
  • Internal support cost is front-loaded: once the adapter layer and characterization tests exist, routine maintenance is low. The danger zone is the first six months, when the wiring is novel and undocumented.
  • Add a runbook covering: how to upgrade the Yii DBAL pair, how to verify quote-character behavior, how to re-baseline the SQLite version matrix.

Scaling

  • SQLite is single-writer regardless of DBAL. This package does not change that. If the workload is write-heavy or multi-tenant with concurrent writers, the correct answer is a different database, not a different driver.
  • The 2.0 performance work is real and relevant: typed ColumnSchemaInterface implementations per datatype (#273) reduce casting overhead, and the new ColumnFactory/ColumnDefinitionBuilder split should make schema introspection cheaper. For read-heavy reporting against SQLite, this is a genuine improvement over 1.x.
  • Connection-per-process is the model. Under Octane, verify connections are re-established after worker reload to avoid holding stale file handles.
  • Memory: schema metadata is cached via PSR-16. With getCacheKey()/getCacheTag() removed (#347), you lose fine-grained invalidation hooks — plan for a coarse TTL or full-flush strategy after schema changes, and make sure that flush is wired into your deploy step.

Failure modes

  • Silent insert failure. insertWithReturningPks() now returns array|false (#339). Code written against 1.x that assumes an array will misbehave. Enforce strict comparison and treat false as a hard error.
  • Backtick residue. Quote character moved from ` to " (#362). Untraced raw SQL fails at runtime, often only on the code path that uses it. Mitigate with a repo-wide grep as a CI lint.
  • Unsigned column exception. (#402) Ported MySQL-flavored schema definitions throw on SQLite. Fail fast at boot via a schema smoke test rather than at first request.
  • FOR UPDATE on SQLite. (#354) The clause parses but SQLite has no row-level locking. Developers porting from PostgreSQL may believe they have a lock they do not have. Document this explicitly, or forbid the clause in code review.
  • JSON behavior relocation. JsonExpressionBuilder moved to yiisoft/db (#337) and yiisoft/json was dropped (#343). A stale pin can leave JSON handling on the wrong package version. Verify JSON round-trip and OVERLAPS semantics in staging.
  • Dual-writer lock contention. Two DBALs on one SQLite file under load produces SQLITE_BUSY. Set a busy timeout and retry policy, or separate the files.
  • Exception-type mismatch. (#364) catch blocks keyed on the old exception class stop catching. Audit error paths; consider catching \Throwable at the adapter boundary and re-throwing domain exceptions.
  • Dependency-graph deadlock. yiisoft/db 2.x pins can block unrelated upgrades. Isolating the package behind an adapter keeps the rest of the app free to move.

Ramp-up

  • Estimate 2–3 engineer-days for a competent Laravel developer to wire the connection, satisfy PSR-17/logger/cache, and get a first query through. Familiarity with Laravel's DB layer actively misleads here — the abstraction is different at every level.
  • Add 3–5 engineer-days to build the adapter layer and characterization tests, which is where the actual value is realized.
  • Add 1–2 weeks of calendar time if 1.x code needs porting, dominated by the quote-character and column-class migrations rather than by volume of code.
  • Learning curve is steep-then-flat. The API is well-factored and readable once the interface hierarchy is understood; the difficulty is entirely in not knowing it, not in it being complex.
  • Mitigation: write the ADR before the code, keep all Yii types behind app-owned interfaces so a future replacement is a one-directory change, and have the one knowledgeable engineer pair with a second engineer for a half-day on the wiring so the bus factor improves immediately.
  • Recommendation to the steering group: approve this only as a scoped, adapter-wrapped sidecar with an explicit exit criterion (the legacy dependency goes away, or a Laravel-native alternative matures). Do not approve it as a primary data layer, and do not accept it as an unexamined transitive dependency — an unowned 2.0 major in the graph is how this becomes an incident rather than a decision.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment