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 Migrations Laravel Package

elnur/database-migrations

A Laravel package for working with database migrations, offering a simple way to organize and run schema changes in PHP applications. It aims to streamline common migration tasks while staying lightweight and easy to integrate.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install and register. composer require elnur/database-migrations. If the package doesn't support package auto-discovery (it's old and low-traffic — check composer.json for extra.laravel.providers), add the service provider to config/app.php under providers. Run php artisan list and look for the package's command (commonly something like db:migrate, migrate:sql, or sql:migrate) — this is your entry point for everything else.

  2. Look at these three things first, in order:

    • The package's config/ file — it defines the migration directory, the tracking table name, and the DB connection used. Publish it (php artisan vendor:publish --provider="Elnur\...\...ServiceProvider") so you can change paths without touching vendor code.
    • The command class in src/ — read how it discovers files, sorts them, and whether it splits on ; or executes whole files. That single detail dictates everything about how you write your SQL.
    • The tracking table's schema — you'll query it during debugging to see what the package believes has run.
  3. First use case. The natural entry point is anything Laravel's Schema builder handles poorly: a CREATE VIEW, a Postgres trigger function, a MySQL stored procedure, or a bulk data backfill. Drop a timestamped .sql file into the configured directory, run the package's migrate command, and confirm the row appears in the tracking table. Once that works, you understand the whole package.

Implementation Patterns

One file per logical change, timestamp-prefixed. Follow the same YYYY_MM_DD_HHMMSS_description.sql convention as native Laravel migrations. The package almost certainly sorts lexically, so consistent zero-padded timestamps matter more than with PHP migrations because you have no class name to fall back on.

Keep native migrations and SQL migrations in separate lanes. The value of this package is that it tracks state in its own table, independent of migrations. Use native migrations for schema you want the Schema DSL for (and want migrate:rollback/migrate:fresh to handle), and reserve SQL files for objects the DSL can't express. Document the split in README/CONTRIBUTING so the next developer doesn't guess.

Write idempotent SQL where the dialect allows it. CREATE TABLE IF NOT EXISTS, CREATE OR REPLACE VIEW, DROP TRIGGER IF EXISTS. Because the package's failure semantics are simple (an error aborts the run), idempotency lets you re-run after a partial failure without hand-editing the tracking table.

Structure for data backfills. Wrap large UPDATE/INSERT ... SELECT in explicit BEGIN; ... COMMIT; only if your file is executed as a single unit and your dialect supports transactional DDL. Otherwise chunk by primary key inside the SQL and make the file re-runnable.

Environment-gated execution in deploy pipelines. Run the package's migrate command in your deploy script before the app comes up, gated on the same --force/--env guard you use for php artisan migrate. Since there's no dependents and only a single star, treat it as your own code: pin the version in composer.json and review the diff on upgrade.

Rollback by paired files. If the package supports a down convention (e.g. foo.down.sql), use it. If it doesn't — and likely it doesn't — keep a sibling *.down.sql file in a database/sql/rollback directory and run it manually. Don't pretend you have automatic rollback.

Multi-connection setups. Point the config at a specific connection rather than relying on the default, especially in apps with a read/write split. Migrations must run against the writer.

Gotchas and Tips

  • Statement splitting is the #1 pitfall. Many "plain SQL" packages split the file on ;, which silently breaks on Postgres $$ ... $$ function bodies, MySQL DELIMITER blocks, semicolons inside string literals, and -- comments. Before writing any procedure or trigger, verify how the package feeds statements to PDO — if it splits naively, keep such objects in a separate file and run them by hand, or patch the runner.
  • No transaction around DDL on MySQL. DDL causes an implicit commit, so a failure mid-file leaves the database half-migrated with no tracking row. Write files so each is either already-applied-safe or small enough to reason about. On Postgres, wrap in explicit BEGIN/COMMIT — but be aware the package may already wrap, and nesting will warn.
  • The tracking table name can collide. If the config default is something generic and you run multiple apps against one schema, override it per-app. Check the config default rather than assuming.
  • Encoding and line endings. Save files as UTF-8 without BOM, LF endings. A BOM before CREATE produces a syntax error that's easy to misread as a permissions problem.
  • Debugging workflow: add -v to the artisan command, tail the DB's error log or storage/logs/laravel.log, and query the tracking table directly (select * from <tracking_table> order by id desc limit 5) to confirm what actually recorded. If a file ran but wasn't recorded, it will re-run next deploy — verify the insert path before assuming success.
  • Don't rely on it for migrate:fresh in tests. RefreshDatabase doesn't know about this package. Either run the SQL migrations in your test bootstrap explicitly, or (better) keep test schema entirely in native migrations and use SQL files only for objects that tests don't touch.
  • Extension points are thin. Expect to extend the provided command class if you need checksums, dry-run, or a --pretend flag — those are the features you'd get for granted from migrate. Subclass, register your own command, and keep the vendor directory pristine.
  • The bus factor is the real risk. One star, zero dependents, single maintainer. Fork it into your org, tag it, and treat the fork as the source of truth. The package is small enough that owning it is cheaper than being surprised by an abandoned dependency.
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.
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus