Not null violation: 7 ERROR: null value in column - Laravel 5.8 - laravel

I don't understand this, I alter my table to add these columns
Schema::table('clusters', function($table)
{
$table->string('ssaEnabled',1)->default('0');
$table->string('ssaBackendUrl')->default(NULL);
$table->string('ssaPortalApiUrl')->default(NULL);
});
in my store() I have this
$cluster->ssaEnabled = Input::get('ssaEnabled','0');
$cluster->ssaBackendUrl = Input::get('ssaBackendUrl','');
$cluster->ssaPortalApiUrl = Input::get('ssaPortalApiUrl','');
$cluster->save();
I kept getting
prod.ERROR: SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column "ssaBackendUrl" violates not-null constraint
Why ??
I set it to default null already
I also add a backup value in my Input::get() in the 2nd param as an empty string
Any hints?
How can I stop that ?

Create a new migration
php artisan make:migration add_nullable_to_ssaBackendUrl_column_on_clusters_table --table=clusters
Updating Column Attributes
The change method allows you to modify the type and attributes of
existing columns.
Schema::table('clusters', function($table)
{
$table->string('ssaBackendUrl')->nullable()->change();
});
Run the migration
php artisan migrate

Related

Using sync with many to many relationship in laravel: PostgreSQL Pivot table doesn't update

I'm getting this error whenever i try to sync an array of inputs to a pivot table:
Illuminate\Database\QueryException
SQLSTATE[23503]: Foreign key violation: 7 ERROR: insert or update on table "items_option_parcel"
violates foreign key constraint "items_option_id_fk_2971521" DETAIL: Key (items_option_id)=(0) is not present in table "items_options". (SQL: insert into "items_option_parcel" ("items_option_id", "parcel_id") values (0, 168))
here is a line of my controller:
$parcel->parcel_options()->sync($request->input('parcel_options', []));
function in the first model:
public function parcelOptionsParcels()
{
return $this->belongsToMany(Parcel::class);
}
function in the 2nd model:
public function parcel_options()
{
return $this->belongsToMany(ItemsOption::class);
}
I found out the issue, i checked my pluck() function, i forgot to pluck the items options ID with their SKUs, that's why every time it says a 0 id is not present in the table because it wasn't getting fetched at all.
I changed this:
$parcel_options = ItemsOption::all()>pluck('item_option_sku')>prepend(trans('global.pleaseSelect'), '');
to this
$parcel_options =
ItemsOption::all()->pluck('item_option_sku','id')->prepend(trans('global.pleaseSelect'), '');

Laravel Database Migration Column altered to Unique and Nullable causing error

I am attempting to integrate social logins with my existing laravel app. I am attempting to change email and password to nullable but I also need email to remain unique. On executing my migration I am getting an error for duplicate key name 'users_email_unique'
Laravel 5, already fixed the issue with enum I had for altering a column.
Schema::table('users', function (Blueprint $table) {
$table->string('email')->unique()->nullable()->change();
$table->string('password')->nullable()->change();
});
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique' (SQL: alter table users add unique users_email_unique(email))
Exception trace:
1 Doctrine\DBAL\Driver\PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:119
2 PDOException::("SQLSTATE[42000]: Syntax error or access violation: 1061 Duplicate key name 'users_email_unique'")
/vendor/doctrine/dbal/lib/Doctrine/DBAL/Driver/PDOStatement.php:117
Edit
If I remove Unique() from email, will it remain unique since that was previously set in a different migration?
You can change the uniqueness behaviour in a new migration by following below:
public function up()
{
Schema::table('contacts', function (Blueprint $table) {
$table->dropUnique(['email']);
});
}
/**
* Reverse the migrations.
*
*/
public function down()
{
Schema::table('contacts', function (Blueprint $table) {
$table->string('email')->unique()->change();
});
}
The Nullable() attribute will stay with the email column, since it was created with it.
It sound like the database is detecting a repeated value. That's impossible with nulls, so it could be an empty string maybe.
If that's the case, you can write a mutator function in your model to check if the value is empty and, set it to null before it goes to the database engine, like this:
public function setNameOfYourAttribute($value) {
if ( empty($value) ) {
$this->attributes['nameofyourattribute'] = NULL;
}
}
Hope it helps.
NOTE:
Full Documentation
Figured this out myself, as mentioned in the comment on the above answer.
Simply because the table was already created with unique() if I remove that it will allow the migration and will also persist the unique() functionality that was in the original User table migration.

Laravel migration: fields that defined as interger wil be treated as auto increment?

Here is my code:
public function up()
{
Schema::create('sysmods', function (Blueprint $table) {
$table->increments('mod_id');
$table->string('mod_name','60');
$table->string('mod_alias_name','60');
$table->integer('mod_tb_id','6');// this will become auto increment?
$table->timestamps();
});
}
when i run the migrate command, it says:
" [PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1075 Incorrect table def
inition; there can be only one auto column and it must be defined as a key"
Then as i check the sql, I found this:
(SQL: create table la_sysmods (mod_id int unsigned not null auto_increm
ent primary key, mod_name varchar(60) not null, mod_alias_name varchar(
60) not null, mod_tb_id int not null auto_increment primary key, created
_at timestamp null, updated_at timestamp null) default character set utf
8 collate utf8_unicode_ci)
The field 'mod_tb_id' which marked as integer has become increments. What's the problem? Thanks!
The second argument for the integer method is the autoIncrement variable. You need to remove it.
The Laravel method
public function integer($column, $autoIncrement = false, $unsigned = false)
{
return $this->addColumn('integer', $column, compact('autoIncrement', 'unsigned'));
}
Change this:
$table->integer('mod_tb_id','6');// this will become auto increment?
To this:
$table->integer('mod_tb_id');
You need to replace your
$table->integer('mod_tb_id','6');// this will become auto increment?
with
$table->integer('mod_tb_id')->length(6);
or
$table->integer('mod_tb_id', false, false)->length(6);
The second argument for integer() method is the flag for autoincrement and the third is for unsigned.
Hope it helps

How to change enum type column in laravel migration?

I am using Laravel 5.1 and I have a table called packages with this structure:
id int(11)
weight decimal(10,2)
weight_unit enum('Kg.', 'Gm.')
I would like to change the weight_unit enum to:
weight_unit enum('Grams','Kgs.','Pounds')
For this I create the following migration:
public function up()
{
Schema::table('packages', function ($table) {
$table->enum('weight_unit', array('Grams','Kgs.','Pounds'))->nullable()->change();
});
}
But when I run the migration I receive an error:
Unknown database type enum requested, Doctrine\DBAL\Platforms\MySqlPlatform
may not support it.
How can I change this enum?
Use the DB::statement method:
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Grams', 'Kgs', 'Pounds')");
This worked for me when adding a new enum value to the modified enum column.
Add the following to the up() method:
DB::statement("ALTER TABLE packages MODIFY weight_unit ENUM('Grams', 'Kgs', 'Pounds', 'new value') NOT NULL");
Then in the down() method you can revert the change that was made:
DB::statement("ALTER TABLE packages MODIFY weight_unit ENUM('Grams', 'Kgs', 'Pounds') NOT NULL");
Note: before the enum value is removed it needs to be changed to another enum value that will be retained.
$table->enum('level', ['easy', 'hard']);
You can add custom constructor to migration and explain to Doctrine that enum should be treated like string.
public function __construct(\Doctrine\DBAL\Migrations\Version $version)
{
parent::__construct($version);
$this->platform->registerDoctrineTypeMapping('enum', 'string');
}
In case you dont want to lose your data and update it with the new values I came up with this solution:
// Include old and new enum values
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Kg.', 'Gm.', 'Grams', 'Kgs', 'Pounds')");
// Replace Kg. with Kgs
Packages::where('weight_unit', 'Kg.')->update(['weight_unit' => 'Kgs']);
// Replace Gm. with Grams
Packages::where('weight_unit', 'Gm.')->update(['weight_unit' => 'Grams']);
// Delete old values
DB::statement("ALTER TABLE packages MODIFY COLUMN weight_unit ENUM('Grams', 'Kgs', 'Pounds')");
This way you can replace your old values with the new ones.
add this before change() call :
DB::getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('enum', 'string');
I think that is fixed on Laravel 10 by adding support for native column modifying.
https://github.com/laravel/framework/pull/45487
So from Laravel 10 you can do this:
Schema::table('jobs', function (Blueprint $table) {
$table->enum('type', ['contract', 'permanent', 'partial'])->change();
});
I tried the same migration on fresh Laravel 9.55.0 and 10.0.2 application:
laravel-9.52.0.jpg
laravel-10.0.2.jpg
I am able to solve this by removing and adding constraints. This has made sure that my existing data is also is intact.
DB::statement("ALTER TABLE purchases DROP CONSTRAINT purchases_ref_check");
$types = ['single', 'monthly', 'biannual', 'amount', 'other'];
$result = join( ', ', array_map(function( $value ){ return sprintf("'%s'::character varying", $value); }, $types) );
DB::statement("ALTER TABLE purchases add CONSTRAINT purchases_ref_check CHECK (ref::text = ANY (ARRAY[$result]::text[]))");
with default value. add this in up():
\DB::statement("ALTER TABLE `patient_appointments` CHANGE `status` `status` ENUM('pending','wait','approved', 'consulted') CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL DEFAULT 'pending';");

Laravel Schema Builder Update Default Value

Trying to setup a migration that will make my already existing "active" field have a default value of "1".
I see in the docs I can use something like:
$table->integer('active')->default(1);
But I tried this in my migration with no success, I guess because the field already exists. Is there a way to correctly manage existing fields using the schema builder?
My current migration:
public function up()
{
Schema::table('scores', function($table){
$table->integer('active')->default(1);
});
}
Edit:
From what I've read so far, this can't be done with the query builder. But when I try to run a raw query:
DB::query("ALTER TABLE `scores` CHANGE COLUMN `active` `active` int(11) NOT NULL DEFAULT '1';");
I'm getting a "method 'query' does not exist error", so I'm guessing this method name was changed I just can't find what it was changed to
Looks like DB::query() was changed to DB::statement()
This did the trick:
DB::statement("ALTER TABLE `scores` CHANGE COLUMN `active` `active` int(11) NOT NULL DEFAULT '1';");

Resources