Laravel migrations: dropping a specific table - laravel

Is there any way/laravel-command to drop a specific table from the production server?

Set up a migration.
Run this command to set up a migration:
php artisan make:migration drop_my_table
Then you can structure your migration like this:
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class DropMyTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
// drop the table
Schema::dropIfExists('my_table');
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
// create the table
Schema::create('my_table', function (Blueprint $table) {
$table->increments('id');
// .. other columns
$table->timestamps();
});
}
}
You can of course just drop and not check for existence:
Schema::drop('my_table');
Read further in the docs here:
https://laravel.com/docs/5.2/migrations#writing-migrations
You may also have to consider dropping any existing foreign keys/indexes, for example if you wanted to drop a primary key:
public function up()
{
Schema::table('my_table', function ($table) {
$table->dropPrimary('my_table_id_primary');
});
Schema::dropIfExists('my_table');
}
More in the docs in dropping indexes etc here:
https://laravel.com/docs/5.2/migrations#dropping-indexes

Related

SQLite Expecting a string as Index Column when dropping a column

<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class RemoveConstructionDateToOrdersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
if (Schema::hasColumn('orders', 'construction_date')) {
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('construction_date');
});
}
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->date('construction_date');
});
}
}
When I am migrating this laravel migration on a sqlite database, I am getting
the following error.
InvalidArgumentException: Expecting a string as Index Column
I found where the problem is after hours of poking around. Looks like the doctrine/dbal package cannot rename/handle/drop?! SQLite columns that already have an index
So my solution was to NOT make any indexes on columns that get later renamed in the migrations
Of course we do want the indexes to exist in MySQL so here's my solution to it.
Schema::table('comments', function (Blueprint $table) {
$table->string('commentable_type', 100)->nullable()->after('id');
//only add index if the connection is mysql
if(config('DB_CONNECTION') === 'mysql'){
$table->index('commentable_type');
}
});
So later when you try to rename the column and using SQLite it works.

Dropping foreign keys in Laravel migration

I have a problem with dropping some foreign keys from my Laravel application. The problem is when I am trying to rollback the migration:
php artisan migrate:rollback
I don't know why I have errors in the console:
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'role_user_user_id_foreign'; check that column/key exists (SQL: alter table role_user drop foreign key role_user_user_id_foreign)
[Doctrine\DBAL\Driver\PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'role_user_user_id_foreign'; check that column/key exists
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1091 Can't DROP 'role_user_user_id_foreign'; check that column/key exists
Below I'm showing my migration class:
class UpdateRoleUserTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
schema::table('role_user',function(Blueprint $table){
$table->foreign('user_id')->references('id')->on('users');
$table->foreign('role_id')->references('id')->on('roles');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign('role_user_user_id_foreign');
$table->dropForeign('role_user_role_id_foreign');
});
}
}
My table in the database has been created by migration class:
class CreateRoleUserTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('role_user', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('role_id')->unsigned();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('role_user');
}
}
In all of the >4.0 versions of Laravel, it allows placing column names into an array, which it will then resolve on its own. I tried to find accompanying docs, but they seem to have left it out.
In your update migration, try this:
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['role_id']);
});
I just had this issue and the problem was due to the fact that $table->dropForeign([column_name]); drops the index and not the column itself. The solution is in the down function drop the index in one block and then drop the actual column in a separate block. They have to be dropped in separate blocks because of something to do with not being able to drop the key in the same connection as where the column is being dropped.
So the down function should look like this:
public function down() {
// drop the keys
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['role_id']);
});
// drop the actual columns
Schema::table('role_user', function (Blueprint $table) {
$table->dropColumn('user_id');
$table->dropColumn('role_id');
});
}
now you can run php artisan migrate to run the up function and php artisan migrate:rollback to run the down command and the error no longer shows.
I have modified your code below.
Add the onDelete() and onUpdate() to your code.
public function up()
{
Schema::table('role_user',function(Blueprint $table) {
$table->foreign('user_id')->references('id')->on('users')->onDelete('CASCADE')->onUpdate('CASCADE');
$table->foreign('role_id')->references('id')->on('roles')->onDelete('CASCADE')->onUpdate('CASCADE');
});
}
public function down() {
Schema::table('role_user', function (Blueprint $table) {
$table->dropForeign(['user_id']);
$table->dropForeign(['role_id']);
});
}
In Laravel 9.x, you do not need to specify a separate deletion of foreign keys.
<?php
use App\Models\Question;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up(): void
{
Schema::create('answers', function (Blueprint $table) {
$table->id();
$table->foreignIdFor(Question::class, 'question_id');
$table->text('correctly');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down(): void
{
Schema::dropIfExists('answers');
}
};

Failing to create new migration

I want to create a new table, users_profile
here is the migration code
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersProfileTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users_profile', function (Blueprint $table) {
$table->increments('id');
$table->string('city');
$table->string('country');
$table->integer('users_id')->unsigned();
$table->foreign('users_id')
->references('id')
->on('users')
->onDelete('cascade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users_profile');
}
}
facing an error
base table or view already exists: 1050 Table "users" already exists
here is the migration code of users
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('users', function (Blueprint $table) {
$table->increments('id');
$table->string('first_name');
$table->string('last_name');
$table->string('email')->unique();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('users');
}
}
Although i am creating a new migration, a new table only i am declaring a primary key of users table as foreign key in users_profiles but facing the above error
help please!
Just a word of advice, Use Laravel Nomenclature to avoid these kind of issues. Always define your table names as plural snakecase and use singular camelcase model to access them.
In your case, change your table name to: user_profiles and use UserProfile model to access it automatically.
Ofocurse you need to change your class name in your migration accordingly: CreateUserProfilesTable
I believe it should resolve your issue.
I believe you are using : php artisan migrate and as users table already exists , running migration for users table again gives that error.
Use: composer dump-autoload and then php artisan migrate:refresh
to rollback all of your migrations and reinstall migrations.
Simple go to your database and drop Schema table ("users") and also remove entry in Schema table ("migrations") and run your migrations again...your problem is solve....

Change tables structures with migration without losing data?

I have read several threads about this but still not exactly my problem.
So in the users table I have a column called role, which is enum type and has two available values: 1 and 2. I set 2 as the default one. Now I want to change it to 1, for example. I created a new migration, ran php artisan migrate and encounter this error:
[Illuminate\DatabaseQueryException]
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'role' (SQL: alter table `u
sers` add `role` enum('1', '2') not null default '1')
[PDOException]
SQLSTATE[42S21]: Column already exists: 1060 Duplicate column name 'role'
Here is code in my CreateUsersTable migration file:
$table->enum('role', ['1', '2'])->default('2');
And I did the same in the new UpdateUsersTable migration file:
$table->enum('role', ['1', '2'])->default('1');
And by the way I can not use php artisan migrate:refresh because it will delete all my data. Where am I doing wrong?
$table->enum('role', ['1', '2'])->default('1')->change();
<?php
use Illuminate\Support\Facades\DB;
use Illuminate\Database\Migrations\Migration;
class UpdateUsersTable extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
DB::statement('ALTER TABLE `users` MODIFY `role` DEFAULT 1;');
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
DB::statement('ALTER TABLE `users` MODIFY `role` DEFAULT 2;');
}
}
Adapted from this answer to another question
In order to do this you have to add ->nullable() or ->default() to every field you add to the migration file.
create a new migration file
php artisan make:migration add_role_to_users_table --table=users
open the created migration file (database\migrations\2021_12_01_050851-add_role_tables.php) and add below code.
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddRoleToUsers extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('users', function (Blueprint $table) {
$table->enum('role', ['1', '2'])->default('1')->comment('1 - admin, 2 - normal'); //added
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('users', function (Blueprint $table) {
$table->dropColumn('role'); //added
});
}
}
?>
Now migration refresh
php artisan migrate:refresh --path=/database/migrations/2021_12_01_050851-add_role_tables.php

Setting Default Value for Primary Key in Laravel Migration for sqlite

I've created the database migration below. What I'd like to do is create an accounts table with an id as a primary key. However, I don't want the key to autoincrement starting at 1. Rather, I'd like it to autoincrement starting at 800500.
Is there a way to set the default value of a primary key like this?
I'm currently using Laravel v4.2.11 and sqlite v3.8.3.
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateAccountsTable extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('accounts', function(Blueprint $table)
{
$table->increments('id')->unsigned()->default(800500);
$table->string('name', 100);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::drop('accounts');
}
}
The default method in the schema builder
Declare(s) a default value for a column
If you need the increment to start at a given value take a look at this answer.
You'd add the query to the migration:
public function up()
{
Schema::create('accounts', function(Blueprint $table)
{
$table->increments('id');
$table->string('name', 100);
$table->timestamps();
});
DB::statement("UPDATE SQLITE_SEQUENCE SET seq = 800500 WHERE name = 'accounts'");
}
There is no 'laravel' way to do this.

Resources