How to delete in couchbase? - couchbase

Hi I am having issues trying to delete entries in couchbase. My entry looks like this,
[ "default": {"status": "SUCCESS", "traceback": null, "result": 13, "task_id": "003bba0e-a9ff-44a5-8c79-7829878eb1bb", "children": []}]
where the entry is a celery task add entry.
I have tried the following queries but I keep getting no result or the entry not being deleted,
DELETE FROM default s WHERE s.task_id = "003bba0e-a9ff-44a5-8c79-7829878eb1bb" RETURNING s
DELETE FROM default WHERE "task_id" = "003bba0e-a9ff-44a5-8c79-7829878eb1bb"
but to no avail.

Your first DELETE statement is correct if the document is a JSON object with a top-level field of task_id, so perhaps your document is not well-formed JSON.
### Add the document to the default bucket
INSERT INTO default (key, value) VALUES ("task1", {"status": "SUCCESS", "traceback": null, "result": 13, "task_id": "003bba0e-a9ff-44a5-8c79-7829878eb1bb", "children": []});
### Delete the document from the default bucket
DELETE FROM `default` s WHERE s.task_id = "003bba0e-a9ff-44a5-8c79-7829878eb1bb" RETURNING s;

Related

Controller (MVC) gives back JSON with "$ref": "15" as reference to other objects

At the moment we get JSON back with references to objects that were rendered previous. We expect that JSON objects are full rendered.
When we get the result of a function in a controller we get a $ref id in stead of the full JSON object. For example:
This is what we expect:
"TaxCode": {
"Name": "Hoog (21%)",
"Rate": 21,
"CreatedOn": "2020-01-06T14:45:28",
"ModifiedOn": "2020-01-23T09:11:27.653",
"DeletedOn": null,
"Id": 1,
"SqlLabelTemplate": null,
"Label": "Hoog (21%)"
},
This is what we get:
"TaxCode": {
"$ref": "15"
},
This is the config setting we currently have:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Serialize;
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = Newtonsoft.Json.PreserveReferencesHandling.Objects;
GlobalConfiguration.Configuration.Formatters.Remove(GlobalConfiguration.Configuration.Formatters.XmlFormatter);
We tried different values in the config with no result.
Somehow there was a config added to the WebApiConfig.cs. So the config in the global.asax was overwritten.
After removing this line from the webapiconfig.cs:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.Objects;
And adding the following config to the Global.asax:
GlobalConfiguration.Configuration.Formatters.JsonFormatter.SerializerSettings.PreserveReferencesHandling = PreserveReferencesHandling.None;
solved all issues.

Update MySQL JSON column filtering in recursive estructure

today I started using MySQL JSON fields and I'm a bit lost
I have the following table:
CREATE TABLE `formulario` (
`id` int NOT NULL AUTO_INCREMENT,
`values` json NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
The JSON "values" has a recursive structure, so that a "section" can have "sections" inside:
[
{
"id": 1,
"sections": [
{
"idSection": 1,
"name": "S1",
"sections": [
{
"idSection": 2,
"name": "S2",
"sections": [...]
}
]
}
]
}
]
Let's suppose that I want to update the "name" attribute of the "section" with id = 2. What I want is to do an "UPDATE" query that somehow updates the "name" value of a specific JSON object, and I don't know how to do a "WHERE" or if there is any way to filter the JSON to get it.
I have tried to use the "JSON_SET" function, but I can't get it to work, considering that I don't know how deep the JSON can be
Extra info: I am using hibernate, but I also don't know if HQL gives you any way to achieve this, or can I build some "NativeQuery" dynamically where I can insert to the "JSON_SET" function the path of what I want to change by building it at runtime

Appending JSON array to existing JSON column

I have some data to be inserted into a MySQL column with the JSON datatype (blob_forms).
The value of the fields column is populated asynchronously, and if the document has multiple pages, then I need to append the data onto the existing row.
So a same table is;
document
document_id INT
text_data JSON
blob_forms JSON
blob_data JSON
The first chunk of data is correctly inserted and it is this data; (A sample)
{"fields": [
{"key": "Date", "value": "01/01/2020"},
{"key": "Number", "value": "xxx 2416 xx"},
{"key": "Invoice Date", "value": "xx/xx/2020"},
{"key": "Reg. No.", "value": "7575855"},
{"key": "VAT", "value": "1,000.00"}
]}
I am using lambda (Python) to handle the database insert, using this query
insertString = json.dumps(newObj)
sql = "INSERT INTO `document` (`document_id`, `blob_forms`) VALUES (%s, %s) ON DUPLICATE KEY UPDATE `blob_forms` = %s"
cursor.execute(sql, (self.documentId, insertString, insertString))
conn.commit()
The problem is, I also want to do an UPDATE too, so that if blob_forms has a value already, it would add the new items in the fields array to the existing objects fields array.
So basically use the original data input a second, so that if it is sent again, with the same document_id it would append to any existing data in blob_forms but preserve the JSON structure.
(Please note other processes write to this table and possibly this row due to the async nature, as the data for the columns can be written in any order, but the document_id ties them all together.
My failed attempt was something like this;
SET #j = {"fields": [{"key": "Date", "value": "01/01/2020"},{"key": "Number", "value": "xxx 2416 xx"},{"key": "Invoice Date", "value": "xx/xx/2020"},{"key": "Reg. No.", "value": "7575855"},{"key": "VAT", "value": "1,000.00"}]}
INSERT INTO `document` (`document_id`, `blob_forms`) VALUES ('DFGHJKfghj45678', #j) ON DUPLICATE KEY UPDATE blob_forms = JSON_INSERT(blob_forms, '$', #j)
I'm not sure that you can get the results that you want with 1 clean query in mysql. My advice would be to make the changes to the array on the client side (or wherever) and updating the entire field without delving into whether there is an existing value or not. I architect all of my api's in this way to keep the database interactions clean and fast.
So far this looks closest;
SET #j = '{"fields": [{"key": "Date", "value": "01/01/2020"},{"key": "Number", "value": "xxx 2416 xx"},{"key": "Invoice Date", "value": "xx/xx/2020"},{"key": "Reg. No.", "value": "7575855"},{"key": "VAT", "value": "1,000.00"}]}';
INSERT INTO `document` (`document_id`, `blob_forms`) VALUES ('DFGHJKfghj45678', #j) ON DUPLICATE KEY UPDATE blob_forms = JSON_MERGE_PRESERVE(blob_forms, #j)

how to overwrite a one to many records in odoo through default API

how to overwrite a one to many records in odoo through odoo API ?
This is my create json, what change I want to make in this json to overwrite(Replace) the existing? lead_product_ids., now it is appending the records. Now i am getting multiple when update the records in this code instead of 0,0 what is the value,
Please help.
{
"jsonrpc": "2.0",
"params": {
"model": "crm.lead",
"method": "create",
"args": [
{
"type": "opportunity",
"name": "Fgtrdhjkkmmmmmmmm1290",
"pro_info": "Fggggggg hhhhhh jkkkkkkknjj hjkll",
"tag_ids": [
6,
0,
[
43,42
]
],
"purposes_id": 3,
"lead_product_ids": [
***0,
0,***
{
"product_uom": 21,
"product_id": 148,
"description": "",
"qty": 1,
"price_unit": 2448,
"expected_price": 2448,
"discount": 0,
"tax_id": [
6,
0,
[
22
]
],
"price_subtotal": 2741.760009765625
}
],
"partner_id": 1592,
"religion": 2,
"age_bucket": "40_45",
"phone": "5695324877",
"mobile": "5695324878",
"locations_id": 157,
"district_id": 157,
"state_id": 593
}
]
}
}
The answer is found in the docstring of the Model.write():
"""
...
This format is a list of triplets executed sequentially, where each
triplet is a command to execute on the set of records. Not all
commands apply in all situations. Possible commands are:
``(0, _, values)``
adds a new record created from the provided ``value`` dict.
``(1, id, values)``
updates an existing record of id ``id`` with the values in
``values``. Can not be used in :meth:`~.create`.
``(2, id, _)``
removes the record of id ``id`` from the set, then deletes it
(from the database). Can not be used in :meth:`~.create`.
``(3, id, _)``
removes the record of id ``id`` from the set, but does not
delete it. Can not be used on
:class:`~odoo.fields.One2many`. Can not be used in
:meth:`~.create`.
``(4, id, _)``
adds an existing record of id ``id`` to the set. Can not be
used on :class:`~odoo.fields.One2many`.
``(5, _, _)``
removes all records from the set, equivalent to using the
command ``3`` on every record explicitly. Can not be used on
:class:`~odoo.fields.One2many`. Can not be used in
:meth:`~.create`.
``(6, _, ids)``
replaces all existing records in the set by the ``ids`` list,
equivalent to using the command ``5`` followed by a command
``4`` for each ``id`` in ``ids``.
.. note:: Values marked as ``_`` in the list above are ignored and
can be anything, generally ``0`` or ``False``.
"""
It's (1, id, {'field_1': value_1,'field_2': value_2,}). But you should use write instead of create because in create it doesn't make any sense to change non-existing records of a x2many field.

How to replace JSON key's value in mysql

I have a mysql JSON column like:
column value
data [{ "report1": { "result": "5"}, "report2": {"result": "6"}, "report3": {"a": "4"}}, {"report1": { "result": "9"},"report4": {"details": "<b>We need to show the details here</b>"}, "report3": {"result": "5"}}]
another instance of data is:
[{ "report1": { "result": "5"}, "report2": {"result": "6"}, "report3": {"a": "4"}}, {"report1": { "result": "9"}, "report3": {"result": "5"},"report4": {"details": "<b>We need to show the details here</b>"}}]
In above record the key is present on 2nd index.
And in this:
[{ "report1": { "result": "5"}, "report2": {"result": "6"}, "report3": {"a": "4"}}, {"report1": { "result": "9"}, "report3": {"result": "5"}}]
The key is not present.
I need to replace {"details": "<b>We need to show the details here</b>"}, i.e. key report4's value with just [], I need now data in this report.
Actually, the logic for generating data have been changed from XML data to JSON for only that key, so, we need to replace it with a blank array, the target type now, without affecting the other data.
Is there any direct solution to that? I'm avoiding creating procedures here.
So, The Target data will be:
[{ "report1": { "result": "5"}, "report2": {"result": "6"}, "report3": {"a": "4"}}, {"report1": { "result": "9"},"report4": [], "report3": {"result": "5"}}]
And yes the keys in JSON are not consistent, means, a key may present in next or previous record in the table but may not present in this record.
The column should be of type JSON to use MySQL's JSON features efficiently. Then use the JSON modification functions, such as JSON_REPLACE.
Since each value contains a JSON array whose size may not be known in advance, you can create a small utility function to modify each element in the array.
create function modify_json(val json)
returns json
deterministic
begin
declare len int default json_length(val);
declare i int default 0;
while i < len do
# Replace the report4 property of the i'th element with an empty list
set val = json_replace(val, concat('$[', i, '].report4'), '[]');
set i = i + 1;
end while;
return val;
end;
With your utility function, update the records:
update table set data = modify_json(data)
where json_contains_path(data, 'one', '$[*].report4');
The records containing at least one element with a report4 property will be updated according to the modify_json function in this case. You could achieve the same thing with multiple update commands that operate on each index of the JSON array separately.
If the column can't be of type JSON for some reason, then you can allow MySQL to coerce the data or your program can marshall the string into a JSON object, modify the data, then serialize it to a string, and update the row.