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

Laravel Sqlite Fluent Drop Foreign Laravel Package

exolnet/laravel-sqlite-fluent-drop-foreign

Provides a workaround for dropping foreign keys on SQLite when using Laravel’s fluent schema builder, so migrations can remove foreign key constraints cleanly despite SQLite’s limited ALTER TABLE support.

View on GitHub
Deep Wiki
Context7

Getting Started

This package patches Laravel's SQLite schema grammar so dropForeign() becomes a fluent, no-op-safe operation instead of throwing RuntimeException: This database driver does not support dropping foreign keys. You reach for it when a single migration has to run against both SQLite (local dev, CI, in-memory tests) and MySQL/Postgres (production).

Requirements as of v1.12.0: PHP 8.3+ and Laravel 12+. PHP 8.2 and Laravel 11 support were removed in this release — check composer.json before upgrading.

composer require exolnet/laravel-sqlite-fluent-drop-foreign

The service provider is auto-discovered; there is no publish step and no config file. Look first at:

  1. The service provider — it's where the grammar/macro override is registered. That tells you exactly which Schema calls are intercepted.
  2. The tests/ directory — the fixtures show which dropForeign() signatures (array, string, explicit index name) are covered.
  3. Your own database/migrations/ for any migration that currently branches on DB::getDriverName().

First use case: delete the driver check from a migration and let it run unchanged.

Schema::table('posts', function (Blueprint $table) {
    $table->dropForeign(['user_id']); // works on sqlite now
});

Implementation Patterns

Write migrations driver-agnostically. The whole point is to remove the if (DB::getDriverName() === 'sqlite') { ... } else { ... } forks. Keep one code path and let the package intercept on SQLite while MySQL/Postgres use the native grammar.

Make down() symmetric. Because the package emulates the drop by rebuilding the table, the reverse migration ($table->foreign('user_id')->references('id')->on('users')) is the real test of correctness. Always exercise migrate:rollback and migrate:refresh locally before merging.

Test suite on SQLite, production on MySQL. This is the highest-value integration: keep phpunit.xml pointed at sqlite/:memory: so RefreshDatabase exercises every dropForeign() in your migration history on every run. Failures surface at PR time instead of during a deploy.

CI matrix after upgrading to v1.12. Drop the php: 8.2 and laravel: 11.* rows from your GitHub Actions matrix in the same commit as the composer.json bump, or the first green build will be followed by a wall of resolver failures.

Use it for the "legacy cleanup" migration. Dropping a foreign key that a previous team added and nobody remembers is exactly the scenario the package exists for — you can write the cleanup without special-casing SQLite and without leaving a permanent driver branch in the repo.

Pair with Schema::withoutForeignKeyConstraints() when the migration does more than one structural change, so the rebuild doesn't trip FK enforcement mid-flight.

Gotchas and Tips

  • v1.12.0 is breaking. PHP 8.2 and Laravel 11 are gone. If you're pinned to Laravel 11, constrain "exolnet/laravel-sqlite-fluent-drop-foreign": "^1.11" and don't let a composer update drift you forward. If you're on Laravel 12 but PHP 8.2, you must upgrade PHP first — the constraint will otherwise fail resolution with a confusing message.
  • Table rebuild semantics. SQLite cannot alter constraints in place; the package recreates the table. Anything not captured by the Blueprint (custom indexes, triggers, WITHOUT ROWID, collations, partial index predicates) may not survive. Diff sqlite_master before and after on any table with hand-written DDL.
  • Constraint naming. dropForeign(['user_id']) resolves the conventional posts_user_id_foreign index name. Custom names must be passed explicitly: dropForeign('my_custom_fk_name'). A "constraint not found" error on SQLite but not MySQL is almost always a naming mismatch.
  • Debugging the generated SQL. Run DB::enableQueryLog() around the migration, or DB::listen(), and inspect the CREATE TABLE ... AS/rename sequence. Inspect the result directly with SELECT sql FROM sqlite_master WHERE type='table' AND name='posts'; — the remaining FK clauses are right there.
  • Transactions. SQLite DDL inside a transaction behaves differently from MySQL; migrations that wrap DDL in DB::transaction() can produce confusing failures. Prefer letting Artisan manage the transaction boundary.
  • Verify both drivers in CI. A migration that passes on SQLite can still fail on MySQL if the constraint name differs — the package makes SQLite permissive, which can mask a name that never existed on production.
  • Watch for native Laravel support. Laravel has been steadily closing the SQLite schema gap. Before each Laravel major, check whether dropForeign on SQLite works without the package; if it does, removing this dependency is a one-line composer remove plus deleting any explicit service provider registration.
  • Extension point. If you need the same emulation for another unsupported operation, mirror the package's registration approach in your own provider rather than forking — the grammar override pattern is small and copyable.
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.
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
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle