Insert null in date field in postgresql using collection - laravel

I am trying to insert an array with date field - end_date in postgresql with Laravel 5.7. But this gives an error -
SQLSTATE[23502]: Not null violation: 7 ERROR: null value in column \"end_date\" violates not-null constraint
I am using Laravel 5.7, Postgresql 9.3
$array = [
"amazon_store_id" => 4
"advertising_profile_id" => 1
"campaign_id" => 123
"name" => "6 shelf 2"
"campaign_type" => "sponsoredProducts"
"targeting_type" => "manual"
"premium_bid_adjustment" => true
"daily_budget" => 15.0
"start_date" => "2014-11-25 09:32:18"
"end_date" => null
"state" => "paused"
"serving_status" => "CAMPAIGN_PAUSED"
"creation_date" => "2014-11-07 10:17:03"
"last_updated_date" => "2018-10-24 12:49:54"
"created_at" => "2018-12-24 09:32:18"
"updated_at" => "2018-12-24 09:32:18"
];
DB::table($table_name)->insert($array->toArray());
Ideally it shall insert the null in the database.

In your migration you can do this to make the column nullable:
public function up()
{
Schema::create('tablename', function (Blueprint $table) {
$table->dateTime('end_date')->nullable();
});
}
->nullable() Designate that the column allows NULL values

In your migration file you have to define the date field as nullable.
Schema::table($table_name, function (Blueprint $table) {
$table->dateTime('end_date')->nullable();
});

Related

How to fix upsert problem when seeding? (laravel)

I have these code below, all seems working but when I try to run unit test it returns an error below.
Here is my seeder (this seeder is called many times in different test cases):
DB::table('sizes')->upsert([
[
'name' => 'jumbo',
'created_at' => date("Y-m-d H:i:s"),
'updated_at' => date("Y-m-d H:i:s"),
],
[
'name' => 'large',
'created_at' => date("Y-m-d H:i:s"),
'updated_at' => date("Y-m-d H:i:s"),
]
], ['id'], ['name']);
And the errors pops out:
Illuminate\Database\QueryException: SQLSTATE[23000]: Integrity constraint violation: 19 UNIQUE constraint failed: sizes.name (SQL: insert into "sizes" ("created_at", "name", "updated_at") values (2021-05-10 12:52:18, jumbo, 2021-05-10 12:52:18), (2021-05-10 12:52:18, large, 2021-05-10 12:52:18) on conflict ("id") do update set "name" = "excluded"."name")
Here is the migration:
Schema::create('sizes', function (Blueprint $table) {
$table->id();
$table->string('name')
->unique();
$table->timestamps();
});
Your migration will result in such table:
id INT AUTO_INCREMENT PRIMARY_KEY
name VARCHAR UNIQUE
created_at TIMESTAMP
updated_at TIMESTAMP
Your seeder when run first time will insert such records:
id
name
created_at
updated_at
1
jumbo
...
...
2
large
...
...
Now, based on laravel's documentation on upsert:
If you would like to perform multiple "upserts" in a single query, then you should use the upsert method instead.
The method's first argument consists of the values to insert or update, while the second argument lists the column(s) that uniquely identify records within the associated table.
The method's third and final argument is an array of the columns that should be updated if a matching record already exists in the database.
The upsert method will automatically set the created_at and updated_at timestamps if timestamps are enabled on the model:
The important point is:
The method's first argument consists of the values to insert or update,
while the second argument lists the column(s) that uniquely identify records within the associated table.
The method's third and final argument is an array of the columns that should be updated if a matching record already exists in the database
That means, your command:
DB::table('sizes')->upsert([
[
'name' => 'jumbo',
'created_at' => date("Y-m-d H:i:s"),
'updated_at' => date("Y-m-d H:i:s"),
],
[
'name' => 'large',
'created_at' => date("Y-m-d H:i:s"),
'updated_at' => date("Y-m-d H:i:s"),
]
], ['id'], ['name']);
Will do this:
check if any record have id of (blank) => no record will match (so upsert will become insert instead)
insert into database, value name=jumbo, and insert into database, value name=large,
this second step will fail since there's already record on database that have name=jumbo (and another record with name=large)
remember that you have name VARCHAR UNIQUE constraint, and this second step violates the UNIQUE constraint
Instead, you should change your seeder into this:
DB::table('sizes')->upsert([
[
'name' => 'jumbo',
'created_at' => date("Y-m-d H:i:s"),
'updated_at' => date("Y-m-d H:i:s"),
],
[
'name' => 'large',
'created_at' => date("Y-m-d H:i:s"),
'updated_at' => date("Y-m-d H:i:s"),
]
], ['name'], ['created_at','updated_at']);
The edited version will do this:
check if any record have name of "jumbo"
no record will match initially (so upsert will become insert first time),
and for subsequent run will match (so upsert will become update for subsequent runs)

Field 'id' doesn't have a default value when import excel file laravel

return new hasilsurvey([
'survey' => $row[1],
'question1' => $row[2],
'question2' => $row[3],
]);
I has setting my table columns 'id' to primary key but still get same problem
Please help my problem
When creating your migration you must define id field as autoincrement:
$table->bigIncrements('id');
If you want to update id field for that table you can do it with this:
$table->bigIncrements('id')->change();

Laravel updating relational table not working

Question 1: Unable to update the record for relational table profiles. End up with the following error.
Error
Illuminate\Database\QueryException
SQLSTATE[42S22]: Column not found: 1054 Unknown column 'user_id' in 'field list' (SQL: update users set user_id = 132, users.updated_at = 2020-03-30 08:48:51 where id = 132)
I have two tables users and profiles with below schema
User Schema
Schema::create(
'users',
function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('username')->unique();
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password')->nullable();
$table->enum('role', ['super', 'admin', 'manager', 'subscriber', 'user'])->default('user');
$table->boolean('is_root')->default(FALSE);
$table->rememberToken();
$table->timestamps();
$table->unique(['username', 'email'], 'users_unique_credentials');
}
);
Profile Schema
Schema::create('profiles', function (Blueprint $table) {
$table->bigIncrements('id');
$table->bigInteger('user_id')->unsigned();
$table->string('key', 191);
$table->longText('value')->nullable();
$table->foreign('user_id', 'profile_uid_fk')
->references('id')
->on('users')
->onDelete('cascade');
$table->unique(['user_id', 'key'], 'profile_unique_key');
});
User Modal - Relation
public function profiles()
{
return $this->hasMany(Profile::class)->orderBy('id');
}
Profile Modal - Relation
public function user()
{
return $this->belongsTo(User::class);
}
User Controller - Update
public function update(UserRequest $request, User $user)
{
$user->email = $request->email;
$user->role = $request->role;
if ($request->has('password')) {
$user->password = Hash::make($request->password);
}
$user->save();
$user->profile()->save($user);
}
dd - $request->all()
Question 2: the user_id is a hidden field in the form. However, I would prefer to pass it from the controller instead. Is there any
way to do it?
array:15 [▼
"_token" => "O3Ardvzz7QvAsYa7aUWn4dbJx1qpCsScykD1fh1S"
"_method" => "PUT"
"email" => "newage#test.com"
"password" => null
"password_confirmation" => null
"role" => "subscriber"
"first_name" => "John"
"last_name" => "doe"
"city" => "Ahmedabad"
"mobile" => "545466555"
"facebook" => "https://facebook.com/profile/pp"
"twitter" => "https://twitter.com"
"youtube" => null
"instagram" => null
"user_id" => "132"
]
you need to change query in user controller to :
$user->profile()->create($user->toArray())->save();
you can also see this Example
You can use the associate method.
$user->profile()->associate($user);
For more info: Docs

Laravel updateOrCreate with composite key

I have a table that's defined thus:
Schema::create('tableA', function (Blueprint $table) {
$table->increments('id');
$table->integer('user_id')->unsigned();
$table->integer('label_id')->unsigned();
$table->date('date');
$table->integer('value');
$table->unique(['user_id','label_id','date']);
$table->timestamps();
});
The table uses a composite key of user_id, label_id and date.
I would like to update the table using the Model::updateOrCreate method thus:
Model::updateOrCreate(
[
'user_id' => $user_id,
'label_id' => $label_id,
'date' => $date,
'value' => $value,
]);
But I get an error if I run the method when a row with the composite key already exists because it seems Laravel doesn't work with composite keys.
For example row
[
user_id:2,
label_id:3,
date:'2019-04-04',
value: 44
]
cannot be updated using
Model::updateOrCreate([
user_id:2,
label_id:3,
date:'2019-04-04',
value: 100
]);
Does this mean there's no way to use updateOrCreate and I need to check each row if it exists before I attempt to add it ?
If you want to update a row based on a user_id the first parameter of the updateOrCreate is an array of fields you are looking to match, and the second contains fields that should update. So from what you are saying I believe you should use this:
Model::updateOrCreate([
user_id => 2,
label_id => 3,
date => new Carbon('2019-04-04')
],
[
value => 100
]);

Laravel 5.4 Duplicate entry for key 'PRIMARY' on sync()

I have Playlist and Track Many To Many relationship with additional order field:
Schema::create('playlist_track', function (Blueprint $table) {
$table->integer('playlist_id')->unsigned();
$table->integer('track_id')->unsigned();
$table->integer('order')->unsigned();
$table->primary(['playlist_id', 'order']);
});
User can delete tracks from playlists and change an order. So this sync method is what I need:
foreach ( $tracks as $key => $track ){
$_tracks[ $track ] = [ 'order' => $key ];
}
$playlist->tracks()->sync( $_tracks );
But I get an error when trying to change an ordering of tracks:
SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry '3-0' for key 'PRIMARY' (SQL: update `playlist_track` set `order` = 0 where `playlist_id` = 3 and `track_id` = 1)
That's because i'm using composite primary key I guess... But I don't know how to make it works
UPD
This is dd( $_tracks )
array:2 [
1 => array:1 [
"order" => 0
]
3 => array:1 [
"order" => 1
]
]
Since it's a pivot table, you can't define foreign key as primary, so remove this:
$table->primary(['playlist_id', 'order'])
Pivot table can have non unique playlist_id values, but with ->primary() you're creating a constraint.
Use an auto-increment, integer column as a primary key:
$table->increments('id');

Resources