How can indexes be checked if they exist in a Laravel migration?
19,085
Solution 1
Using "doctrine-dbal" that Laravel uses is better solution:
Schema::table('persons', function (Blueprint $table) {
$sm = Schema::getConnection()->getDoctrineSchemaManager();
$indexesFound = $sm->listTableIndexes('persons');
if(array_key_exists("persons_body_unique", $indexesFound))
$table->dropUnique("persons_body_unique");
});
Solution 2
The mysql query
SHOW INDEXES FROM persons
will give you back all of the indexes on the table, however it includes additional info other than just the names. In my setup, the column containing the name is called Key_name
so lets get a collection of key names
collect(DB::select("SHOW INDEXES FROM persons"))->pluck('Key_name')
And since its a collection you can use contains
so finally we have:
if (collect(DB::select("SHOW INDEXES FROM persons"))->pluck('Key_name')->contains('persons_body_unique')) {
$table->dropUnique('persons_body_unique');
}
Solution 3
In the simple form, you can do this
Schema::table('persons', function (Blueprint $table) {
$index_exists = collect(DB::select("SHOW INDEXES FROM persons"))->pluck('Key_name')->contains('persons_body_unique');
if ($index_exists) {
$table->dropUnique("persons_body_unique");
}
})
Related videos on Youtube
Author by
Oladipo
Updated on June 30, 2020Comments
-
Oladipo almost 4 years
Trying to check if a unique index exists on a table when preparing a migration, how can it be achieved?
Schema::table('persons', function (Blueprint $table) { if ($table->hasIndex('persons_body_unique')) { $table->dropUnique('persons_body_unique'); } })
Something that looks like the above. (apparently, hasIndex() doesn't exist)
-
Roland almost 6 yearsThis shouldn't be the accepted answer as it is not cross-dbms ("portable", not vendor-specific). The answer by @admirko is much more better as it goes over Laravel's underlaying Doctrine layer and not over a "native query".
-
Roland almost 6 yearsAs mentioned above, this should be the right answer as it goes over Laravel's Doctrine and does not use a native query.
-
Filip Filipovic over 5 yearsI can confirm this works on 5.2, after i installed the doctrine-dbal package from the repo.
-
RyanNerd about 5 yearsBe aware that
listTableIndexes()
will return the name of indexes in lower case. -
JKOlaf over 3 yearsMinor add to make copy/paste for other migrations in your future you can use the $table object to get the name.
$indexesFound = $sm->listTableIndexes($table->getTable());