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

Database Laravel Package

nette/database

Nette Database is a lightweight yet powerful PHP database layer with an intuitive query builder, safe parameter binding, and support for MySQL, PostgreSQL, SQLite, MS SQL, and Oracle. Clean API plus optional ORM-like conveniences make queries simple and secure.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit: conditional, not default. This is not a Laravel package. nette/database is a standalone, framework-agnostic DB layer (Connection + Explorer + Selection/ActiveRow) with its own PDO wrapper, its own DI extension for Nette DI, and its own Tracy debug panel. Laravel already ships two overlapping stacks — the DB facade/Query Builder and Eloquent. Adopting nette/database inside a Laravel app means running a third data-access paradigm unless it strictly replaces one of the two, which is rarely viable on a live codebase. The honest framing for stakeholders: this is not an "add a Composer package" decision, it is an "own and maintain a bridge" decision.

Where it genuinely fits:

  • Legacy Nette → Laravel migration. The strongest case by far. During a phased port, Nette-era code keeps working against nette/database while new feature work lands on Eloquent. The package's stability record (backports through PHP 8.5 on the 3.2 line, steady 3.2.x patch cadence) makes it a credible "keep the old world alive" dependency.
  • Oracle / MS SQL Server targets. Laravel has no first-class Oracle driver (community packages only) and weaker MS SQL introspection. nette/database ships drivers for MySQL, PostgreSQL, SQLite, MS SQL Server, and Oracle in one package, with a real reflection layer for Table, Column, Index, ForeignKey. For an enterprise client anchored on Oracle or MSSQL, that breadth is the only defensible differentiator.
  • Schema-reflection tooling. The 3.2.1+ reflection layer is lighter than booting Eloquent's model/schema stack for a read-only introspection or data-catalog job.

Where it does not fit: a greenfield or MySQL/Postgres-only Laravel app. Everything the description advertises — fluent parameterized builder, row objects, transactions, multi-DB support — is already covered by Laravel's Query Builder with better framework integration. Opportunity score of 67.5 against a 52.6 overall reads to me as "interesting tech, weak contextual fit," which matches my read.

Integration feasibility: medium-low, and the hard part is connections, not queries.

  • No service provider, no facade, no config publishing, no Laravel-native logging. All of that is a bespoke bridge we own.
  • Transaction composition is the blocker. Two independent PDO connections mean Eloquent writes inside DB::transaction() are invisible to nette/database reads on a separate connection. Any code path that mixes the two silently loses read-your-writes and can deadlock against itself under load. On v3.x this is partially mitigable by sharing the underlying PDO handle (Connection::getPdo() exists); v4.0.0-RC1 removes getPdo() and getDsn(), which removes exactly the escape hatch we would need. That is a material argument for pinning v3.2.x and treating v4 as a future migration, not an adoption target.
  • v4 RC is not production-ready for us. Drivers for non-PDO extensions, merged Connection/Explorer, and default-on convertBoolean / convertDateTime are attractive, but an RC with removed interfaces (IRow, IRowContainer) and removed methods is a moving target. Also undocumented in the supplied sources: the PHP floor for v4.
  • Licensing is unresolved. NOASSERTION on a commercially consumed dependency requires legal review before we build on it. Nette packages are typically BSD-3-Clause, but "typically" is not a sign-off. Treat this as a gate, not a footnote.
  • The dataset's Dependents: 0 is not credible and should be struck from the decision record — nette/database is a core dependency of the Nette framework stack. 539 stars is a fair signal of niche, not of abandonment.

Technical risk:

  • High — dual connection / dual transaction model, unbounded blast radius if mixed read-write paths emerge.
  • Medium — ActiveRow lazy loading. The repo's own agent documentation flags the Explorer layer as a separate "world" with sharp edges around lazy execution, accessed-column narrowing, and N+1. That is a performance landmine that will not be obvious in code review to Laravel-native engineers.
  • Medium — upgrade churn. The 3.2 line carries repeated BC-adjacent changes: zero-dates → NULL, time columns resetting date to 0001-01-01, TINYINT(1) → bool, DECIMAL precision 0 → int, convertBoolean default flip in v4. Row-shape contracts we build on are not stable across minor versions.
  • Low — SQL injection. Parameterized builder via SqlPreprocessor is mature and the IN (?) handling was hardened.
  • Low-Medium — Selection::transaction() nesting is supported, but nesting semantics differ from Laravel's savepoint-based nesting. Must be documented explicitly for the team.

Key questions to resolve before commitment:

  1. Which engines are actually in scope? If Oracle/MSSQL is not on the list, this evaluation ends here.
  2. Who owns transaction boundaries in a mixed codebase, and can we enforce "one writer per aggregate" as a written rule plus static analysis?
  3. Can we pin to 3.2.x and share the PDO handle, or does an anticipated v4 upgrade break that strategy?
  4. Has legal cleared the NOASSERTION license?
  5. Do we accept a community-maintained, single-maintainer-risk dependency for a system of record?
  6. What is the bridge's ongoing owner and budget — this is not a set-and-forget integration?

Integration Approach

Stack fit. nette/database 3.2.x targets PHP 8.1+ with explicit support through 8.5, and Laravel 10/11 sit at 8.1/8.2 — so the runtime matrix is compatible. Dependency surface is small (nette/utils, optionally nette/di); the DI extension is only needed under Nette DI and should be bypassed so we don't drag Nette's container into a Laravel app. PSR-4 autoloading coexists cleanly with Laravel's Composer setup. Where fit breaks down is the framework seam: Laravel's container, config, and DB facade have no knowledge of Nette\Database\Connection, and nette/database has no knowledge of Laravel's connection config, retry policy, or query listener.

Migration path (recommended, phased):

  1. Isolate. Introduce nette/database only behind a dedicated namespace (App\Legacy\Db or similar) with a thin repository interface per aggregate. No controller, job, or model touches Explorer directly. The interface is the exit plan — write it as though the package will be removed.
  2. Single connection, single owner. If we take the v3.2.x path, construct Nette\Database\Connection from the same PDO instance Laravel already holds so both layers share one connection and one transaction. If sharing proves fragile, fall back to a dedicated, explicitly read-only connection and enforce that at the repository level — never allow writes on the sidecar.
  3. Bridge the framework seam. One service provider that binds Explorer/Connection singletons from config/database.php, publishes a config file, and registers a query listener into Laravel's logging/Telescope so nette/database traffic isn't invisible in production. Skip the Tracy ConnectionPanel entirely — it is a Nette/Tracy artifact and does not belong in a Laravel runtime; wire the package's query events into Laravel's logging instead.
  4. Harden the boundary. Document ActiveRow pitfalls (lazy execution, accessed-column narrowing, N+1) in an ADR and lint for ActiveRow usage outside the legacy namespace. Map DeadlockException, LockTimeoutException, CheckConstraintViolationException, and ConnectionLostException (3.2.9+) into our existing retry policy — note that Laravel already has causedByConcurrencyError, so pick one policy and delete the other to avoid double-retry.
  5. Retire. Track call-site count per legacy repository. If a repository has zero call sites for two release cycles, remove it and eventually drop the dependency.

Compatibility notes to bake into the plan:

  • Pin to an exact 3.2.x version and treat every bump as a reviewed change — 3.2.x has shipped row-shape BC breaks in minor releases.
  • Do not design against getPdo() / getDsn() for anything load-bearing if a v4 move is on the roadmap; the connection-sharing trick in step 2 is v3-only.
  • The 3.2.9 Docker Compose test-DB setup is a genuine gift — adopt it for our CI matrix so driver-specific behaviour (Oracle limit/offset, MSSQL indexes) is tested rather than assumed.

Sequencing. Legal clearance and a two-day read-only spike precede any committed work. Spike scope: one real Oracle/MSSQL query path, one transaction-sharing proof, one query-log capture. Only after the spike passes do we sequence: service provider → read-only repositories → write paths with documented transaction ownership → observability → deprecation tracking. Do not attempt writes in phase one.

Operational Impact

Maintenance. The 3.2 line is actively maintained — PHP 8.5 support, a steady release cadence, and a 3.2.9 release that added meaningful exception taxonomy plus test infrastructure. That is better than many community packages. But the maintenance burden we absorb is the bridge: config binding, query logging, retry-policy translation, and the ADR that stops engineers from mixing Eloquent and Explorer in one unit of work. Budget this as a standing line item, not a one-off integration cost. The v4 RC signals a forthcoming BC-heavy major, which means a planned migration project roughly 12–18 months out.

Support. Community-maintained under the Nette umbrella with no commercial support tier. Effective maintainer concentration is high — a real bus-factor consideration for a system-of-record dependency. Documentation lives on nette.org and in the repo's docs/, is Nette-idiomatic, and has zero Laravel framing. Our Laravel-native engineers will not find answers by pattern-matching to Eloquent; expect the bridge owner to become an internal SME and to write the internal docs themselves. The repo's own agent-facing documentation explicitly warns that the core and Explorer layers are "two independent worlds" with sharp edges — treat that as an authoritative onboarding warning.

Scaling. The package adds little overhead itself; it wraps PDO and inherits whatever connection behaviour PDO and the driver provide. It does not provide connection pooling, read/write splitting, or query caching — Laravel's connection config does, so keep those concerns in Laravel and treat nette/database as a consumer of an already-configured handle. The real scaling risk is behavioural: ActiveRow's lazy execution and accessed-column narrowing turn a single logical view into a fan-out of queries, and N+1 at the Explorer layer will not show up in Laravel's usual Eloquent-oriented tooling unless the query listener is wired in first. Under Oracle, verify applyLimit offset behaviour on the pinned version — 3.2.8 shipped a fix for OciDriver returning inconsistent results with differing offsets, which tells you this path is less travelled.

Failure modes to design for:

  • Split-connection inconsistency — writes and reads on different connections produce stale reads and phantom lock contention. Mitigation: single shared connection, or hard read-only enforcement on the sidecar.
  • Divergent transaction semantics — nested Selection::transaction() does not behave like Laravel's savepoints. Mitigation: forbid nesting across the boundary; one owner per unit of work.
  • Silent row-shape drift on upgrade — convertBoolean/convertDateTime default-on in v4, zero-date → NULL, TINYINT(1) → bool, getInsertId() returning int. Mitigation: contract tests asserting exact row types per repository, run on every dependency bump.
  • Lost observability — the Tracy ConnectionPanel is unusable in Laravel and removed interfaces in v4 further reduce hooks. Mitigation: query listener registered in the service provider, alerting if no nette/database queries are captured (a silent listener is itself a failure).
  • Driver-specific exceptions escaping retry logic — 3.2.9's DeadlockException/LockTimeoutException/ConnectionLostException are only useful if the retry policy is written against them. Mitigation: map them explicitly and test with fault injection.
  • Unresolved license — non-technical but operationally fatal if discovered late. Mitigation: gate at phase zero.

Ramp-up. Two distinct curves. For engineers, the API is genuinely approachable — a PDO-like surface with a fluent builder, and Selection/ResultSet ergonomics are close enough to Laravel's builder that a competent PHP developer is productive in a day. The second curve is the dangerous one: understanding when ActiveRow executes, how column narrowing changes generated SQL, and why mixing it with Eloquent transactions is unsafe takes materially longer and is learned by incident unless it is taught. Plan a half-day internal workshop and an ADR with worked examples. Estimate 2–3 weeks for the bridge and first repository, plus a 10–15% ongoing maintenance tax on the legacy surface, against which you weigh the cost of a full Eloquent port. For an Oracle/MSSQL estate that port cost is high enough to justify this; for MySQL/Postgres it is not.

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.
mydnic/volet-feature-board
wmde/fundraising-phpcs
friendlylabs/surveyr
mg-techlegend/laravel-notify-africa
islamabdurahman/laravel-sms-service
dmhendricks/b2-sdk-php
aplicativa/laravel-admin
ezavalishin/vkma
jackardios/laravel-json-api-paginate
viral/laravel-adminpanel
dieppk/log-viewer
daimakuai-ext/helpers
codexshaper/php-blade-view
abraxas81/charts
adamlien/laravel-cas
quimgc/tasks
sistem-atc/bank-sdk
core45/laravel-cookieconsent
projectsend/community-modules
ovac/laravel-hubtel-payment