bulk or batch update in knex.js - sql

I'm working with on nodejs with knex.js and sql as a database I have a record of 4000 data in array of object I have to update it into a table, which is currently taking more than 10 minutes. I wanted to reduce the time taken.
this is the records
const records = [
{ ID: "45159", UnitCost: "1", country: "GB" },
{ ID: "45209", UnitCost: "2", country: "GB" },
];
currently I'm mapping through each record and writing this condition
const response = await baseQueryBuilder
.clone()
.where("country", countryCode)
.where({ID:id})
.update({UnitCost:UnitCost});
is there any method that we can do batch or bulk upload so that the time can be reduced. Thanks.

Related

Is there a way to run the supplied prisma query as a raw sql query?

I have been stuck with this and similar dilemmas for a while now and can't seem to find an acceptable solution. Prisma currently doesn't allow for upsertMany in it's queries, or in my case a nested upsertMany. I have found some accepted solutions and the most popular one is using $transaction from prisma to write a loop of upserts which doesn't work for me as each query contains up to 200 items to upsert (currently testing 100 items takes roughly 10sec to run so it really isn't an acceptable solution). Prisma offers the ability to use $queryRaw to use a raw SQL query which may offer a more acceptable solution. I've supplied the code to their currently accepted solution as well as the query (that isn't currently possible) that I'm hoping someone could help me turn into a raw sql query or a better solution.
Their accepted solution:
prisma.$transaction(data.map((d) =>
prisma.MODEL.upsert({
where:{
id: d.id
},
update:{
foo:d.foo,
},
create:{
foo: d.foo,
bar: d.bar
},
}),
),
);
How I would need to implement it as I would like to create one MODEL with a related array of MODELS and another array of related MODELS:
let transactionOne = prisma.$transaction(
arrayOne.map((d)=>
prisma.MODEL.upsert({
where:{
id: d.id,
},
update:{
foo: d.foo,
},
create:{
foo: d.foo,
bar: d.bar,
},
}),
)
);
let transactionTwo = prisma.$transaction(
arrayTwo.map((d)=>
prisma.MODEL.upsert({
where:{
id: d.id,
},
update:{
foo: d.foo,
},
create:{
foo: d.foo,
bar: d.bar,
},
}),
)
);
let data = await prisma.MODEL.create({
data:{
foo: foo,
bar: bar,
example:{
connect: transactionOne.map((a)=>({id: a.id})),
},
exampleTwo:{
connect: transactionTwo.map((b)=>({id: b.id})),
},
},
});
My example above like mentioned before takes just over 10 seconds with 100 items and may possibly require 200 items so 20 seconds per call. Is there an easier way to make this faster or like I said a way to create a raw SQL query with the same results?
Thanks for any help!

Get Empty Rows in TypeORM

I'm trying to write a typeORM query which includes multiple where clauses. I am able to achieve this via where option as follows:
const categories = [
{ name: 'master', categoryTypeId: 2, parentId: 1, locationId: null },
{ name: 'food', categoryTypeId: 3, parentId: null, locationId: null }];
const rows = await Repo.find({
where: categories.map((category) => ({
name: category.name,
categoryTypeId: category.categoryTypeId,
locationId: category.locationId
})),
});
I would want to maintain the mapping b/w the input array and the rows returned. For example, I know that the second category doesn't exist in the DB. I would want to have an empty object in the rows variable so that I know which categories didn't yield any result.
Upon research I have found that we can do something with SQL as mentioned here. But, I'm not sure how do I translate into typeORM if I can.

How to convert Json to CSV and send it to big query or google cloud bucket

I`m new to nifi and I want to convert big amount of json data to csv format.
This is what I am doing at the moment but it is not the expected result.
These are the steps:
processes to create access_token and send request body using InvokeHTTP(This part works fine I wont name the processes since this is the expected result) and getting the response body in json.
Example of json response:
[
{
"results":[
{
"customer":{
"resourceName":"customers/123456789",
"id":"11111111"
},
"campaign":{
"resourceName":"customers/123456789/campaigns/222456422222",
"name":"asdaasdasdad",
"id":"456456546546"
},
"adGroup":{
"resourceName":"customers/456456456456/adGroups/456456456456",
"id":"456456456546",
"name":"asdasdasdasda"
},
"metrics":{
"clicks":"11",
"costMicros":"43068982",
"impressions":"2079"
},
"segments":{
"device":"DESKTOP",
"date":"2021-11-22"
},
"incomeRangeView":{
"resourceName":"customers/456456456/incomeRangeViews/456456546~456456456"
}
},
{
"customer":{
"resourceName":"customers/123456789",
"id":"11111111"
},
"campaign":{
"resourceName":"customers/123456789/campaigns/222456422222",
"name":"asdasdasdasd",
"id":"456456546546"
},
"adGroup":{
"resourceName":"customers/456456456456/adGroups/456456456456",
"id":"456456456546",
"name":"asdasdasdas"
},
"metrics":{
"clicks":"11",
"costMicros":"43068982",
"impressions":"2079"
},
"segments":{
"device":"DESKTOP",
"date":"2021-11-22"
},
"incomeRangeView":{
"resourceName":"customers/456456456/incomeRangeViews/456456546~456456456"
}
},
....etc....
]
}
]
Now I am using:
===>SplitJson ($[].results[])==>JoltTransformJSON with this spec:
[{
"operation": "shift",
"spec": {
"customer": {
"id": "customer_id"
},
"campaign": {
"id": "campaign_id",
"name": "campaign_name"
},
"adGroup": {
"id": "ad_group_id",
"name": "ad_group_name"
},
"metrics": {
"clicks": "clicks",
"costMicros": "cost",
"impressions": "impressions"
},
"segments": {
"device": "device",
"date": "date"
},
"incomeRangeView": {
"resourceName": "keywords_id"
}
}
}]
==>> MergeContent( here is the problem which I don`t know how to fix)
Merge Strategy: Defragment
Merge Format: Binary Concatnation
Attribute Strategy Keep Only Common Attributes
Maximum number of Bins 5 (I tried 10 same result)
Delimiter Strategy: Text
Header: [
Footer: ]
Demarcator: ,
What is the result I get?
I get a json file that has parts of the json data
Example: I have 50k customer_ids in 1 json file so I would like to send this data into big query table and have all the ids under the same field "customer_id".
The MergeContent uses the split json files and combines them but I will still get 10k customer_ids for each file i.e. I have 5 files and not 1 file with 50k customer_ids
After the MergeContent I use ==>>ConvertRecord with these settings:
Record Reader JsonTreeReader (Schema Access Strategy: InferSchema)
Record Writer CsvRecordWriter (
Schema Write Strategy: Do Not Write Schema
Schema Access Strategy: Inherit Record Schema
CSV Format: Microsoft Excel
Include Header Line: true
Character Set UTF-8
)
==>>UpdateAttribute (custom prop: filename: ${filename}.csv) ==>> PutGCSObject(and put the data into the google bucket (this step works fine- I am able to put files there))
With this approach I am UNABLE to send data to big query(After MergeContent I tried using PutBigQueryBatch and used this command in bq sheel to get the schema I need:
bq show --format=prettyjson some_data_set.some_table_in_that_data_set | jq '.schema.fields'
I filled all the fields as needed and Load file type: I tried NEWLINE_DELIMITED_JSON or CSV if I converted it to CSV (I am not getting errors but no data is uploaded into the table)
)
What am I doing wrong? I basically want to map the data in such a way that each fields data will be under the same field name
The trick you are missing is using Records.
Instead of using X>SplitJson>JoltTransformJson>Merge>Convert>X, try just X>JoltTransformRecord>X with a JSON Reader and a CSV Writer. This skips a lot of inefficiency.
If you really need to split (and you should avoid splitting and merging unless totally necessary), you can use MergeRecord instead - again with a JSON Reader and CSV Writer. This would make your flow X>Split>Jolt>MergeRecord>X.

Fastest way to insert 1 million rows to realm on React Native?

I know mysql and realm are different structures but,
Is there a way to quickly insert 1 million records like LOAD DATA INFILE as in mysql for realm on react native?
The api returning 1 million records and it takes 25 minutes to write schema.
My method:
Realm.open({ schema: [EnvanterSchema] }).then(realm => {
realm.write(() => {
response.data.forEach(obj => {
realm.create("Inventory", obj);
});
});
data = [{
barcode: "25836693",
Item: "Men Shoes",
Brand: "brand",
Qty: "x",
Size: "L"
},....]
react native: 0.57.0
realm: 2.16.0

How to get more than 200 data from a data store

I would like to link TestCase TestFolder and TestSet.
To do so I start 2 WsapiDataStore queries one on TestFolder and one on TestSet.
Then I parse the data and get the matching TestCase.
Unfortunatly I have not found the way to get more than 200 elements for each queries or to
index the starting index of the queries.
The code I use for a WsapiDataStore query is
_GetTestSetStore : function(TestFolder, container) {
var TestSet_Store = Ext.create('Rally.data.WsapiDataStore', {
model : 'TestSet',
fetch : [ 'FormattedID', 'TestSet' ],
pageSize : PageSize,
autoLoad : true,
listeners : {
load : function(TestSet_Store, TestSet_Data, success) {
if (success) {
container._CleanStore(TestSet_Store, TestSet_Data, TestFolder, container);
} else {
alert('TestSet store query failed');
}
}
}
});
},
Could you help please
Rally.data.wsapi.Store has a config property limit.
You may set limit to Infinity, no quotes.
limit : Number
The total number or records to retrieve with the initial load Defaults to one page worth. To retrieve all records specify Infinity