I'm working on a project where I need to update many rows at once per coin Id.
in order to update all coins values, Im getting them all from the API, so for example I have back:
$coinsList= [[id="bitcoin", symbol="btc", name="Bintcoin"],[id="etherium", symbol="eth", name="Etherium"]];
and the database table columns is the following:
**| id | coin_id | symbol | name |**
now, I want to update all values to the database, according to the id only, so this is what I did:
// first get ids from my table
$exist_ids = Coinlist::all('coin_id')->pluck('coin_id')->toArray();
//get all ids to update (to ignore other ids):
$updatable_ids = array_values(array_intersect($exist_ids, $allCoinIds));//result for example is: array("bitcoin","etherium");
//and now, update the database:
Coinlist::whereIn('coin_id', $updatable_ids)
->update([
'symbol' => $coinsList[$key]['symbol'],
'name' => $coinsList[$key]['name'],
'updated_at' => now()
]);
the problem is, I don't have the "$key" in order to update the right row, what am I missing here?
Thanks!
Here is a good way to solve it:
in the beginning, I used this library: https://github.com/mavinoo/laravelBatch
to update many dynamic rows, but it was really slow, then thanks to Yasin, I moved to: https://github.com/iksaku/laravel-mass-update and now it works way better.
the implementation is simple, add a simple code to the Model class, then add:
User::massUpdate(
values: [
['username' => 'iksaku', 'name' => 'Jorge González'],
['username' => 'gm_mtz', 'name' => 'Gladys Martínez'],
],
uniqueBy: 'username'
);
while uniqueBy is the key for the row, and add other columns values to change them dynamically.
Related
i'm working with sensitive data hope you can help find if there any wrong in code's writing
i have list of suppliers in my database i added column 'cost'
i'm trying to update and insert cost for existing suppliers from specific query
and i created model and migration to get foreign keys too by adding the puled supplier id from the query
....
$suppliers_data = $suppliers_query->fetchall(PDO::FETCH_ASSOC);
foreach ($suppliers_data as $supplier_data) {
$supplier_name = $supplier_data['supplier_name'];
$cost_rate = $supplier_data['Cost'];
if (!Supplier::where('supplier', $supplier_name)->exists()) {
Supplier::insert([
'supplier' => $supplier_name,
'cost_rate' => $cost_rate
]);
} else {
Supplier::update([
'cost_rate' => $cost_rate // does this will update cost for the current supplier ?
]);
}
$supplier_id = Supplier::where('supplier', $supplier_name)->pluck('supplier_id');
Test::insert($supplier_id);
}
$supplier_count = test::count();
Test::update(['test_data_count' => $supplier_count]);
Updating table data with supplier name is not correct here I believe. Instead of using supplier name in where condition using particular supplier id is recommended for better application. Names can be duplicate so its not a good idea to use supplier name in where.
In your current code I have 2 things to say :
You need to add where in update eloquent to work properly
Supplier::where('supplier', $supplier_name)
->update([
'cost_rate' => $cost_rate // this will update cost for the current supplier
]);
Or to minimalize the code you can use updateorCreate method instead of making insert and update in the if() else() condition
Supplier::updateOrCreate(
['supplier' => $supplier_name],
['cost_rate' => $cost_rate]
);
I am trying to setup a favourites button on an article. The following code works ...
public function favouriteNotfavouriteArticleParent(Request $request){
$data = [];
$data['user_id'] = Auth::id();
$data['person_id'] = GetPersonData()['id'];
$data['article_id'] = $request->get('article_id');
$data['action'] = $request->get('action');
UserFavourites::updateOrCreate($data,$data);
}
However, i want it to firstly check for any existing values set for that article ID. If it has favourite set and notfavourite is clicked, it should remove the favourite table row.
At the minute it just adds a row for favourite and notfavourite. I've attached a screenshot of the current sql behaviour.
Any help is massively appreciated!
UpdateOrCreate takes two arguments. The first argument is an array of attributes to look for and the second argument is an array of attributes to change. If there isn't a row in the database that has attributes from the first array the arrays will essentially be combined to make a new row in the database.
To achieve what you're after you could do the following:
UserFavourites::updateOrCreate([
'article_id' => $request->input('article_id'),
'user_id' => auth()->id(),
], [
'person_id' => GetPersonData()['id'],
'action' => $request->input('action'),
]);
The above will look for a row that matches the article_id and user_id and then either update the person_id and action for that row or (if the row doesn't exist) create a new row with all the attributes.
I want to insert data to one table (called Startups) which has 2 "BelongsTo" relations, I found how to do this with one table (One to Many) in a good Laravel's documentation but I'm beginner in this area and I don't know how to insert data to related to 2 different tables (Categories - Contacts) in one common table (Sturtups), to understand this better please see the image I attached below
Here is my code (please don't pay attention to Sessions, it doesn't matter in that case):
$category_id = Session::get('category_id');
$country_id = Session::get('country_id');
$new_contact = new Contact([
'name' => Session::get('contact_name'),
'phone' => Session::get('contact_phone'),
'email' => Session::get('contact_email')
]);
$country = Country::find($country_id);
$country->contacts()->save($new_contact);
$new_startup = new Startup([
'name' => Session::get('startup_name'),
'description' => Session::get('startup_description'),
'url' => Session::get('startup_url'),
'logo' => Session::get('logo_name')
]);
$category = Category::find($category_id);
$category->startups()->save($new_startup);
$contact = Contact::find( $country->contacts()->id );
$contact->startups()->save($new_startup);
Database Relations image:
image of relations between tables in the DB
Additional info: I have this error:
"General error: 1364 Field 'contact_id' doesn't have a default value"
I know why that error happens (I'm trying to create Startup without id of contact)
I just want to know how insert data in that case
Thank you guys for any help!
Answer to your question is:
make that field nullable in database migration so this error will not occur
$table->unsignedInteger('contact_id')->nullable();
i have a code like this ,
$request = Yii::$app->request;
$post = $request->post();
$filesettingid = $post['filesettingid'];
$checkboxValue = $post['selection'];
for($i=0;$i<sizeof($checkboxValue);$i++) {
$store = Yii::$app->db->createCommand('SELECT id FROM store WHERE port='.$checkboxValue[$i])->queryAll();
$storeid = $store[$i]['id'];
Yii::$app->db->createCommand()->insert('tes',
[
'id' => $i+1,
'filesetting_id' => $filesettingid,
'store_id' => $storeid
])->execute();
}
what i want is, each i insert the new data, id will generate automaticly like 1,2,3,4.
the problem in above code is, the ID always be 1.
is it possible to make it real?
so what i want is :
First time insert, id = 1, second is id = 2 , and that is happen automatically.
Have you considered setting database engine to auto increment values with each insert?
Take as an example Yii2 default user table. ID filed is auto incremented, and you don't have to worry about setting it problematically. Every time you send a new insert engine increments ID filed by itself.
See default migration under "advanced template"\console\migrations\m130524_201442_int. (your file name might be different depending on the Yii2 version)
$this->createTable('{{%user}}', [
'id' => $this->primaryKey(),
'username' => $this->string()->notNull()->unique(),
'auth_key' => $this->string(32)->notNull(),
'password_hash' => $this->string()->notNull(),
'password_reset_token' => $this->string()->unique(),
'email' => $this->string()->notNull()->unique(),
'status' => $this->smallInteger()->notNull()->defaultValue(0),
.........
], $tableOptions);
When setting 'id' to primary key database automatically knows to auto increment it. If you already have a table the ID field is not primary key you can use the followign migration:
$this->alterColumn('{{%databaseName}}', 'columnName', $this->integer()->notNull().' AUTO_INCREMENT');
You can also set it from management console, or run a SQL query. Depending on database engine you are using this might look a little different but the concept is the same.
MYSQL:
In MySQL workbench right click on table in question, select Alter Table and check NNm and AI next to column you want auto increment. See Screenshot
Or run command:
ALTER TABLE `dbName`.`nameOfTheTable` MODIFY `columnName` INT AUTO_INCREMENT NOT NULL;
I am a bit rusty on my SQL, so if it does not work let me know I will get you right command.
Hope this helps. Good luck.
Here is my code -
$updatecompany = DB::table('Companies')
->where('ID', (int)$companyid)
->update(array(
'CompanyName' => $companyname,
'CompanyAddress' => $companyaddress,
'CompanyEmail' => $companyemail,
'ContactName' => $contactname,
'CompanyCity' => $companycity,
'CompanyState' => $companystate,
'CompanyZip' => $companyzipcode,
'CompanyPhone' => $companyphone,
));
$updatecompany is always 0. What might be the problem?
One of most possible reasons is that you are updating with the same data in the database.
There needs one out of the box solution, of course if you can do it.
So, no rows are updating, even if the SQL is correct.
Here is my suggestion:
Add a new column updatedOn in DB Table Companies.
The type should be TIMESTAMP and add attribute ON UPDATE CURRENT_TIMESTAMP.
This way you will always get row affected and hence you get return value other than 0.
You don't need to cast $companyId to an integer there. It does not help Laravel's query builder.
Use dd($companyId) and dump the variable before you run the query and find out what it is.