Updating Existing Column Attributes - Laravel 5 Migration - php

I have
a existing column called cpe_mac. I created it via migration like this :
$table->string('cpe_mac')->default(NULL)->nullable();
I want
I want to add this ->unique() to that column, without having to drop it and re-add.
I've tried
$table->string('cpe_mac')->unique();
Migration File
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AlterCaptivePortalTable212017 extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->unique();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->default(NULL)->nullable();
});
}
}
I kept
getting
SQLSTATE[42701]: Duplicate column: 7 ERROR: column "cpe_mac" of relation "captive_portals" already exists
Is there a way to achieve this without having to drop my existing column? I have a lot client data that can't be deleted.

Schema::table('users', function (Blueprint $table) {
$table->string('cpe_mac')->unique()->change();
});
https://laravel.com/docs/5.0/schema#changing-columns

You need to use change() method:
Schema::table('captive_portals', function (Blueprint $table) {
$table->string('cpe_mac')->unique()->change();
});
Alternatively, you may create the index after defining the column. For example:
$table->unique('email');
https://laravel.com/docs/5.4/migrations#indexes

I had the same issue and this is the solution for Laravel 5.6:
Step1: run this command: composer require doctrine/dbal
step2:run this command:php artisan make:migration THE
-NAME_YOU_WANT --table=TABLENAME
step3: in the added migration, add $table->string('cpe_mac')->unique()->change(); in Schema::table part.
step4: run this command: php artisan migrate

If the column is already defined you can use:
$table->unique('cpe_mac');

Related

How can I modify DB structure in Laravel without truncating tables?

I have defined a DB table structure below.
If I want to modify a table column:
From
$table->string('active',1);
To:
$table->string('active',1)->nullable(); // allow null values
Every time I run the migration script, my tables will be truncated.
Is there a way to define a table structure and have it be modified to correct structure WITHOUT dropping the table?
Here is my code for now:
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class VTUser extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::create('Z_user', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nickname')->unique();
$table->string('email')->unique();
$table->string('passhash');
$table->string('keygen');
$table->string('active',1)->nullable();
$table->string('banned',1);
$table->string('admin',1);
$table->string('step',1);
// $table->rememberToken();
// $table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('Z_user');
}
}
There can be two ways of achieving this -
Either you can rollback the migration with php artisan migrate:rollback --step=1 and then change the up function with $table->string('active',1)->nullable();
Create a new migration to update the table by doing $table->string('active',1)->nullable(); in this new migration.

Php artisan migrate gives different result with the same code

pic1
pic2
Pic 2 is the usual laravel migration tables that i created. Pic 1 is the laravel migration tables that i newly created. They have the same code with same foreign key only with different attributes name. Why is pic 1 only have varchar(191) instead of varchar(255), and the foreign key doesnt apply from migrations anymore? Before pic 1, i did ran some stuff on terminal for deployment purpose like npm build. Is the terminal the cause of this?
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()
{
Schema::create('calibrations', function (Blueprint $table) {
$table->id();
$table->string('Identification_No');
$table->foreign('Identification_No')->references('Identification_No')->on('fieldequips');
$table->string('Calibration_point');
$table->date('Expired_Date');
$table->date('Calibration_Date');
$table->date('Next_Due_Date');
$table->string('Correction_factor');
$table->string('Validated_by');
$table->date('Validated_Date');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::dropIfExists('calibrations');
}
};
In app/Providers/AppServiceProvider.php you should change Schema::defaultStringLength(191) to Schema::defaultStringLength(255), I guess

How to add new column to existing table in laravel

I am adding new column name title in my table tasks. But I am getting an error that this column does not exist in that table. Can anybody help me to resolve that error. Here is my code:
php artisan make:migration add_title_to_tasks_table --table="tasks" and then added this code
Schema::table('tasks', function (Blueprint $table) {
$table->string('title');
});
to new table file created
To Alter table and add column.
/**
* Run the migrations.
*
* #return void
*/
public function up() {
Schema::table('tasks', function (Blueprint $table) {
$table->string('title')->after('id');
// to change column datatype or change it to `nullable`
// or set default values , this is just example
$table->string('title')->default('Test')->change();
});
}
You can refere documentation here, Laravel Migration
For those who are new to laravel and looking for a solution, please follow the steps
1). php artisan make:migration add_title_to_tasks_table --table="tasks"
2). Edit the newly created file in the migrations folder and add the below.
public function up() {
Schema::table('tasks', function (Blueprint $table) {
$table->string('title')->after('id');
// to change column datatype or change it to `nullable`
// or set default values , this is just example
$table->string('title')->default('Test')->change();
});
}
3). Run the migrations command.
php artisan migrate
Do the following:
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('tasks', function (Blueprint $table) {
$table->string('title')->after('your-column-name');
});
}
Replace 'your-column-name' with your existing column name.
Save the file. From terminal, execute:
php artisan migrate
The above command will add the column to your table.
You are getting that error because you are not running the migrate command.
Whenever you create a migration file, you must execute the above command in order to see the changes in your database table.
Also, if the new column does not exist in the models $fillable property, you will have to add it there as well..
/**
* The attributes that are mass assignable.
*
* #return array
*/
protected $fillable = [
'title', // <-- new column name
// .. other column names
];
Failing to do update the $fillable property will result in MassAssignmentExecption
Hope this helps you out. Happy Coding. Cheers.

laravel 5 - How can i add ->index() to existing foreign key

Framework: Laravel 5.2
Database: MySQL
PHP: 7.0
I have the table "pops":
Schema::create('pops', function (Blueprint $table) {
$table->string('id')->primary()->index();
$table->string('ab_test_parent_id')->nullable();
$table->string('cloned_parent_id')->nullable();
$table->timestamps();
});
And the table "conversions":
Schema::create('conversions', function (Blueprint $table) {
$table->string('id')->primary()->index();
$table->integer('users')->default(null);
$table->string('name',256)->default(null);
$table->string('pop_id');
$table->foreign('pop_id')->references('id')->on('pops')->onDelete('cascade')->onUpdate('cascade');
$table->timestamps();
});
I have set a foreign key (pop_id) in the "conversions" table. Now does it's mean that the foreign key (pop_id) is also a index? if not... what i need to do in order to make it a index?
Thank?
You can just do this.
<?php
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddIndexToLeads extends Migration {
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('leads', function(Blueprint $table)
{
$table->index('trader_id');
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('leads', function (Blueprint $table)
{
$table->dropIndex(['trader_id']);
});
}
}
credit to #bobbybouwmann
Here is a perfect solution for you.
Up
$table->string('poptin_id')->index('poptin_id');
Down
$table->dropIndex(['poptin_id']);
Suggestion to fix your migrations
$table->string('id')->primary()->index();
replace above with below
$table->increments('id');
and fix your foreign key as below
$table->integer('poptin_id')->index('poptin_id')->unsigned();
I was facing problem when i just write :-
$table->index('column_name');
So to be more exact first you need to create column with desired column type then assign it to be index like this :-
$table->string('column_name');
$table->index('column_name');
//or
$table->string('column_name')->index();
I hope this helps
Laravel only adds a foreign key constraint and doesn't add index implicitly. But some databases such as MySQL automatically index foreign key columns.
If you need to add index to a field in another migration. Then you could do
$table->index('email');

PHPUnit doesn't seem to be running Laravel Migration

I've got an issue where I'm running some tests in laravel 5.4 via phpunit
I'm using an in memory sqlite database for testing
I've got a test class which i've removed bunch of other stuff from so it effectively looks like
<?php
namespace Tests\Unit;
use App\User;
use App\Order;
use Tests\TestCase;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class OrderTest extends TestCase
{
use DatabaseMigrations;
/** #test */
function can_update_status()
{
// This is empty, it fails on this test because its alphabetically the first test in the whole suite.
}
}
I've recently created a new migration which adds the "paid" column
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class AddStatusToOrders extends Migration
{
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('completed');
$table->boolean('paid')->default(0);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('completed')->default(0);
$table->dropColumn('paid');
});
}
}
However whenever I run this test I get an error saying the paid column doesn't exist - even after a composer du
PHPUnit 6.0.7 by Sebastian Bergmann and contributors.
...................................E
Time: 10.69 seconds, Memory: 46.00MB
There was 1 error:
1) Tests\Unit\OrderTest::can_mark_as_paid
Illuminate\Database\QueryException: SQLSTATE[HY000]: General error: 1 no such column: paid (SQL: update "orders" set "paid" = 1, "updated_at" = 2017-04-05 15:27:11 where "id" = 1)
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:647
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Caused by
Doctrine\DBAL\Driver\PDOException: SQLSTATE[HY000]: General error: 1 no such column: paid
/Users/owen/Sites/1st-choice-spares/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:79
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:470
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:640
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Caused by
PDOException: SQLSTATE[HY000]: General error: 1 no such column: paid
/Users/owen/Sites/1st-choice-spares/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOConnection.php:77
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:470
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:640
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:607
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:477
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Connection.php:416
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Query/Builder.php:2145
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:768
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:581
/Users/owen/Sites/1st-choice-spares/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Model.php:501
/Users/owen/Sites/1st-choice-spares/app/Order.php:62
/Users/owen/Sites/1st-choice-spares/tests/Unit/OrderTest.php:95
Does anybody have any ideas why this would be happening, and how I can resolve it? It might be worth adding I've tried changing the column names etc and the same issue is happening with that
Thanks
UPDATE
If I comment out the lines in the down migration e.g $table->dropColumn('paid');
Then it continues to run - however I'm struggling to understand why the down method would be running before the up has been run?
Update 2
It seems the above finding was due to the column not getting created in the first place, if i suppress that error, the original error appears that the column doesn't exist - which suggests the migration failed to create it.
According to laravel documentation
Dropping or modifying multiple columns within a single migration while using a SQLite database is not supported.
And although you not trying to modify or drop multiple columns ,you are trying to drop and create in one single migration and in both cases ALTER TABLE query is executed ,and the problem here is the limitations of ALTER TABLE query of sqlite .
You can separate each statement like this:
/**
* Run the migrations.
*
* #return void
*/
public function up()
{
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('completed');
});
Schema::table('orders', function (Blueprint $table) {
$table->boolean('paid')->default(0);
});
}
/**
* Reverse the migrations.
*
* #return void
*/
public function down()
{
Schema::table('orders', function (Blueprint $table) {
$table->boolean('completed')->default(0);
});
Schema::table('orders', function (Blueprint $table) {
$table->dropColumn('paid');
});
}

Categories