In Java we have batch execution like the java code below:
Statement statement = null;
statement = connection.createStatement();
statement.addBatch("update people set firstname='John' where id=123");
statement.addBatch("update people set firstname='Eric' where id=456");
statement.addBatch("update people set firstname='May' where id=789");
int[] recordsAffected = statement.executeBatch();
how to do the same in rails ActiveRecord?
You can give this a try. Seems like what you're after.
# Updating multiple records:
people = { 1 => { "first_name" => "David" }, 2 => { "first_name" => "Jeremy" } }
Person.update(people.keys, people.values)
Quoted: https://cbabhusal.wordpress.com/2015/01/03/updating-multiple-records-at-the-same-time-rails-activerecord/
To fit the post requirements, it translates to:
people = {
123 => { "firstname" => "John" },
456 => { "firstname" => "Eric" },
789 => { "firstname" => "May" }
}
Person.update(people.keys, people.values)
Please note that translating the above into SQL still yields multiple queries
Thanks to Rails 6, you can now perform bulk update using upsert_all method for exemple.
More details available there: https://www.bigbinary.com/blog/bulk-insert-support-in-rails-6
Be aware that unique_by option is not supported when the database is MySQL but it works great for Postgresql.
Related
I just find directus headless cms
Looks awesome. It resolve many uses cases for me.
But I am concerned about how to achieve transactions, aggregate functions or complex queries. I understand that maybe is out scope.
If a custom endpoint or graphql allow me execute a stored procedure i will have all my needs achieved.
Is it possible?
Hi finally I find how to use custom endpoints to do plain querys, including stored procedures.
Maybe is possible implement a module for add admin gui option for that, I try work in that, for the moment this is the example for a select:
use Directus\Application\Http\Request;
use Directus\Application\Http\Response;
return [
'' => [
'method' => 'GET',
'handler' => function (Request $request, Response $response) {
$container = \Directus\Application\Application::getInstance()->getContainer();
$dbConnection = $container->get('database');
$tableGateway = new \Zend\Db\TableGateway\TableGateway('directus_users', $dbConnection);
$query = $tableGateway->getAdapter()->query("select * from productos where 1=1");
$result = $query->execute();
if ($result->count() > 0) {
$returnArr = array();
while ($result->valid()) {
$returnArr[] = $result->current();
$result->next();
}
if (count($returnArr) > 0) {
return $response->withJson([
'data' => [
$returnArr,
],
]);
}
}
return "{}";
},
],
];
Sorry for my bad English.
The following is coded in the Laravel framework:
QUERY
$shipping = DB::table('shipping')->where('country',$delivery->country)->first();
$data= json_decode(json_encode($shipping),true);
RESULT
array (
'id' => 3,
'carrier' => 'EN',
'country' => 'AU',
'rates_json' => '{"rates": [{"international": [{"zone4": [{"to_kg": "2", "total": "1", "from_kg": "1"}, {"to_kg": "4", "total": "2", "from_kg": "3"}]}]}]}',
)
In the MySQL database, I stored "rates_json" in a "JSON" datatype column. The attribute "from_kg" and "to_kg" is a range.
I intend to retrieve the total if a value is between the range. For instance, if value 1.5 is between 1 and 2 then the total is 1.
Your help is appreciated.
Thank You.
Since your question is not clear,
I can only give you a hint, what you can do.
foreach (json_decode($data['rates_json'])->rates as $rates) {
foreach ($rates->international as $international) {
foreach ($international->zone4 as $zone) {
if ($zone->from_kg <= $zone->total && $zone->total <= $zone->to_kg)
{
// do whatever you want here.
dump($zone->total);
}
}
}
}
Let me know for any adjustments.
I use laravel 5.6
I have a json file containing 500 thousand records. I want to create a logic to check whether the id of each record already exists or not in the database. If it doesn't already exist, then there will be a data insert process. If it already exists, there will be a data update process
I have made logic. I just want to make sure whether my logic is effective or not
My logic code like this :
$path = storage_path('data.json');
$json = json_decode(file_get_contents($path), true);
foreach ($json['value'] as $value) {
$data = \DB::table('details')->where('id', '=', $value['Code'])->get();
if ($data->isEmpty()) {
\DB::table('details')->insert(
[
'id' => $value['Code'],
'number' => $value['Number'],
...
]
);
}
else {
\DB::table('details')
->where('id', '=', $value['Code'])
->update([
'id' => $value['Code'],
'number' => $value['Number'],
...
]);
}
}
The code is working. But the process seems really long
Do you have another solution that is better?
updateOrCreate
You may also come across situations where you want to update an existing model or create a new model if none exists. Laravel provides an updateOrCreate method to do this in one step. Like the firstOrCreate method, updateOrCreate persists the model, so there's no need to call save():
// If there's a flight from Oakland to San Diego, set the price to $99.
// If no matching model exists, create one.
$flight = App\Flight::updateOrCreate(
['departure' => 'Oakland', 'destination' => 'San Diego'],
['price' => 99]
);
in your case your code should be like this (create Details model first) :
$path = storage_path('data.json');
$json = json_decode(file_get_contents($path), true);
foreach ($json['value'] as $value) {
Details::updateOrCreate(
[ 'id' => $value['Code'] ],
[ 'number' => $value['Number'], ... ]
);
}
i think that's the best way to do it. Eloquent return's a collection so you cant just validate that your string is null.
Trying to create a new jira ticket of specific requestType, but it is nested two levels deep. Tried few possible alterations, but no luck. Here's the code I have,
require 'jira-ruby' # https://github.com/sumoheavy/jira-ruby
options = {
:username => jira_username,
:password => jira_password,
:site => 'https://jiraurl/rest/api/2/',
:context_path => '',
:auth_type => :basic,
:read_timeout => 120
}
client = JIRA::Client.new(options)
issue = client.Issue.build
fields_options = {
"fields" =>
{
"summary" => "Test ticket creation",
"description" => "Ticket created from Ruby",
"project" => {"key" => "AwesomeProject"},
"issuetype" => {"name" => "Task"},
"priority" => {"name" => "P1"},
"customfield_23070" =>
{
"requestType" => {
"name" => "Awesome Request Type"
}
}
}
}
issue.save(fields_options)
"errors"=>{"customfield_23070"=>"Operation value must be a string"}
Also tried passing a JSON object to customfield_23070,
"customfield_23070": { "requestType": { "name": "Awesome Request Type" } }
still no luck, get the same error message.
If it helps, this is how customfield_23070 looks like in our Jira,
Does anyone know how to set requestType in this case, please? Any help is greatly appreciated!!
It seems that for custom fields with specific data types (string/number), you must pass the value as:
"customfield_1111": 1
or:
"customfield_1111": "string"
instead of:
"customfield_1111":{ "value": 1 }
or:
"customfield_1111":{ "value": "string" }
I'm not sure but you can try this possible examples:
eg.1:
"customfield_23070"=>{"name"=>"requestType","value"=>"Awesome Request Type"}
eg.2:
"customfield_23070"=>{"requestType"=>"Awesome Request Type"}
eg.3:
"customfield_23070"=>{"value"=>"Awesome Request Type"}
eg.4
"customfield_23070"=>{"name"=>"Awesome Request Type"}
for ref there are 2 methods depending upon the fields you are interacting with
have a look here '
updating-an-issue-via-the-jira-rest-apis-6848604
' for the applicable fields for update via verb operations, the other fields you can use examples as per above,
you can use both methods within the same call
{
"update": {"description": [{"set": "Description by API Update - lets do this thing"}]},
"fields": {"customfield_23310": "TESTING0909"}
}
Ok, I think I found how to do it.
You need to provide a string, and that string is the GUID of the RequestType.
In order to get that GUID. You need to run the following in a scriptrunner console:
import com.atlassian.jira.component.ComponentAccessor
def issue = ComponentAccessor.issueManager.getIssueByCurrentKey("ISSUE-400546") //Issue with the desired Request Type
def cf = ComponentAccessor.customFieldManager.getCustomFieldObjectByName("Tipo de solicitud del cliente") //Change it to the name of your request type field
issue.getCustomFieldValue(cf)
Source: https://community.atlassian.com/t5/Jira-Software-questions/how-to-set-request-type-value-in-while-create-jira-issue/qaq-p/1106696
I've written up the AR query below, but have one problem with a where clause. On the Payout model there is a comp_builder_id and there's also a comp_builder_id on a ContractLevel.
I want to add a where clause to this query to get the data where the Payout model's comp_builder_id is equal to the ContractLevel model's comp_builder_id.
payouts = Payout.includes(:comp_builder => {
:contract_levels => {
:transmittal => [
{:appointment_hierarchies => :child},
:appointment_cases
]
}
})
.includes(:product)
.includes(:payor)
.where(products: { :id => self.product.id })
.where(appointment_cases: { :case_id => self.id })
.where(transmittals: { :id => appointment_case.transmittal_id })
.where(contract_levels: { :transmittal_id => appointment_case.transmittal_id,
:appointment_id => Transmittal.find(appointment_case.transmittal_id).low,
:comp_builder_id => # ? payout's comp builder id ? })
How can this be done in Active Record? In the last few where clauses I'm referencing different variables, those can be ignored as this query is just a snippet.
You can pass a string into the where statement:
User.include(:parent).where('users.parent_id = parents.id')
Basically if you know what you want the where statement to look like in raw SQL then you can just pass it in as a string into the where statement.
That is the only way I know of to make complex where statements in ActiveRecord.
Just make sure to remember that you need to reference the column names, not the model names.