JSON_MERGE_PATCH with null values (in Javascript) - javascript

As written in the docs, JSON_MERGE_PATCH will remove each value that is set to null, the following example will remove the header value from my settings json field
const data = JSON.stringify({header: null, otherdata: ...})
await connection.query(UPDATE shops SET JSON_MERGE_PATCH(settings, ?), data)
However what if I want to set the value to null, If I surround the header: 'null', with quotes, you can guess it: it enters 'null' as a string into my database.
Does anyone know if it's possible to have mysql update my json field with a null value?

As there doesn't seem to be a pure MySQL solution for this problem, you might be better off implementing this in JavaScript.
You'd implement this something like this:
Fetch all records you want to modify some ID
Use a solution like How can I merge properties of two JavaScript objects dynamically? to merge the objects
Update all records with the new value
An alternate approach could be to use JSON_SET for each object key you have:
UPDATE shops SET JSON_SET(settings, '$.header', null)
-- Then repeat for each json key you want to modify

Related

How to create an item with an index in DynamoDB?

I have been looking everywhere on AWS docs for any information on this and can find absolutely none. The only answer I keep getting everywhere I look is how to query or scan using a secondary index, on already-indexed data. But how do you add a value to the index-attribute of an item in the first place? I am using AWS SDK for JavaScript so JS-specific info would be most helpful, but any info on this would be so much better than what AWS has provided.
I tried to add an item with params like the following, where I simply used the names of indexes as attributes (date and timestamp):
const params = {
TableName: 'Posts_Table',
Item: {
'username' : user,
'image_id' : uuid(),
'date' : date,
'timestamp' : timestamp
}
}
But what ended up happening is date and timestamp were simply added as normal attributes that aren't able to be queried.
You've got some fundamental misunderstanding going on. You don't give enough code or examples for me to guess what you're really attempting. For example, I don't know what your table's keys are. So here's a primer:
You only write items to the base table (never directly to an index). Items can have a variety of attributes. Each item must have unique key attributes in the base table.
You can create a GSI against the table, including after the table has data. When constructing the GSI you select what its key attributes will be.
When you want to use the GSI you must specify it in the query as your Scan or Query target.
Are you trying to write to the index? You can't.
Are you trying to query the index by pointing at the base table? You can't.
Are you trying to write an item to the base table without specifying its primary keys? You can't.
How to create an item with an index in DynamoDB?
You can not create an item without an index in DynamoDB.
When you create a table, you specify the Primary Key which is your index.
When you add an item, you have to provide the Primary Key.
You can also make use of Global Secondary Indexes which technically create a new table with that index under the hood.
But what ended up happening is date and timestamp were simply added as normal attributes that aren't able to be queried.
If you want to be able to query an attribute, that attribute has to be a Primary Key (Partition or Composite) or a Global Secondary Index.

Automatically stringifying object when inserting to a MySQL JSON column with knex

Let's jump straight to an example code:
create table test_json_table
(
data json not null
);
I can insert to the table like this:
const columns = { data: "{ some_json: 123 }" }; // notice that the data column is passed as string
await knex('test_json_table').insert(columns);
And get data from the table like this:
await knex('test_json_table').select();
// returns:
// [
// { data: { some_json: 123 } } // notice that the data is returned as parsed JavaScript object (not a string)
// ]
When inserting a row the JSON column needs to be passed as a serialised string. When retrieving the row, an already parsed object is returned.
This is creating quite a mess in the project. We are using TypeScript and would like to have the same type for inserts as for selects, but this makes it impossible. It'd be fine to either always have string or always object.
I found this topic being discussed at other places, so it looks like I am not alone in this (link, link). It seems like there is no way to convert the object to string automatically. Or I am missing something?
It'd be nice if knex provided a hook where we could manually serialise the object into string when inserting.
What would be the easiest way to achieve that? Is there any lightweight ORM with support for that? Or any other option?
You could try objection.js that allows you to declare certain columns to be marked as json attributes and those should be stringified automatically when inserting / updating their values https://vincit.github.io/objection.js/api/model/static-properties.html#static-jsonattributes
I haven't tried if it works with mysql though. I don't see any reason why it wouldn't.
I think the easiest way using jsonb data type. mysql json type
We prefer postgresql for this kind of problem at office, easier and solid database for your problem.
Well you could call your own function before inserting that converts all objects to string and call it every time before you insert.
You can probably wrap knex to do it automatically as well.

How to fill a select with default object by ajax

I do have a JSON string which I receive by ajax which is correctly ordered:
{"label":"Gr\u00f6\u00dfe","values":{"4302":"XS","4184":"S","4185":"M","4186":"L","4187":"XL","4188":"XXL","5165":"3XL","4340":"4XL"}}
This JSON fills a select. The problem is, that the options are automatically reordered ( I don't know why? ) based on the value key which means that I do not get the correct option order for the select.
The option looks like:
S,M,L,XL,XXL,XS,4XL,3XL
The correct order should be
XS,S,M,L,XL,XXL,3XL,4XL
What can I do to get the correct order?
In JavaScript there is no guaranteed order for the properties on objects. Instead, you should use an array in your JSON to ensure order. Something like this:
{"label":"Gr\u00f6\u00dfe","values":[{"4302":"XS"},{"4184":"S"}, ...]}
You can format the objects in the values array anyhow you'd like, but the idea is when concerned with order, use arrays.

JavaScript + MySQL: use fields as parameter in result

I'm quite new to JavaScript and I have the following issue:
I have a Node.JS server on which a webclient can connect and execute functions. One function is to look into a MySQL database and gather information.
The query is done right and I obtain the correct raw information as for example:
Here is my code:
So I correctly get the column names using the fields (fields[0].name = Count_0)variable and I am able to get the correct value using the result (result[0].Count_0 = Gray).
However, I am unable to merge the two lines in order to create the list of colors using something like this in a loop: result[0].fields[0].name = Gray
Is there an easier way to do this or not ?
Thanks,
Nicola.
In Javascript, you can use the [] operator to access a variably-named property in an object.
Instead of using result[0].fields[0].name, use
result[0][fields[0].name]
You won't get any runtime errors for accessing a property that doesn't exist, so you'll want to check whether that value is undefined before using it somewhere else.
It seems you want to get the color. If so, you can get the color by this
let color = result[0][fields[0].name];
The idea is use fields[0].name as key of result[0].
This is the breakdown of above single line.
let key = fields[0].name;
let color = result[0][key];

DOJO: Adding multiple conditions for querying dojox.grid.DataGrid

I'm trying to create a DOJO DataGrid populated using a dojo.data.ItemFileReadStore with very simple json data which has an ID and a description.
When an event occurs, i need to filter the rows displayed based on the IDs.
When its a single ID, i can fix it by just adding myGrid.setQuery({ID:"someIdIWant"});
Is there some way i can filter more than 1 ID in the same piece of codde? For ex i want to filter ID1 and ID2 to be shown.
I do not have a REST url exposed, my data is populated as javascript variables.
Can i still JsonQueryRestStore using just json data in JS vars or dojo.data.ItemFileReadStore?
The dojo.data.ItemFileReadStore supports using regular expressions in the query. The code internal to the ItemFileReadStore uses dojo.data.util.filter.patternToRegExp() to identify whether or not the string value in your query could be parsed as a regular expression. However, to be more precise, you can pass a RegExp object in your query. The two options look like this:
myGrid.setQuery({ID:"123|124"});
// or
myGrid.setQuery({ID: new RegExp("123|124")});
Both examples fetch the two items with ID "123" and "124" respectively.

Categories