ReQL command: update
Command syntax
table.update(object | function[, durability="hard", return_changes=False, non_atomic=False, ignore_write_hook=False]) → object selection.update(object | function[, durability="hard", return_changes=False, non_atomic=False, ignore_write_hook=False]) → object singleSelection.update(object | function[, durability="hard", return_changes=False, non_atomic=False, ignore_write_hook=False]) → object
Description
Update JSON documents in a table. Accepts a JSON document, a ReQL expression, or a combination of the two.
The optional arguments are:
-
durability
: possible values arehard
andsoft
. This option will override the table or query’s durability setting (set in run). In soft durability mode RethinkDB will acknowledge the write immediately after receiving it, but before the write has been committed to disk. -
return_changes
:-
True
: return achanges
array consisting ofold_val
/new_val
objects describing the changes made, only including the documents actually updated. -
False
: do not return achanges
array (the default). -
"always"
: behave asTrue
, but include all documents the command tried to update whether or not the update was successful. (This was the behavior ofTrue
pre-2.0.)
-
-
non_atomic
: if set toTrue
, executes the update and distributes the result to replicas in a non-atomic fashion. This flag is required to perform non-deterministic updates, such as those that require reading data from another table. -
ignore_write_hook
: IfTrue
, and if the user has the config permission, ignores any write hook when performing the update.
Update returns an object that contains the following attributes:
-
replaced
: the number of documents that were updated. -
unchanged
: the number of documents that would have been modified except the new value was the same as the old value. -
skipped
: the number of documents that were skipped because the document didn’t exist. -
errors
: the number of errors encountered while performing the update. -
first_error
: If errors were encountered, contains the text of the first error. -
deleted
andinserted
: 0 for an update operation. -
changes
: ifreturn_changes
is set toTrue
, this will be an array of objects, one for each objected affected by theupdate
operation. Each object will have two keys:{"new_val": <new value>, "old_val": <old value>}
.
RethinkDB write operations will only throw exceptions if errors occur before any writes. Other errors will be listed in
first_error
, anderrors
will be set to a non-zero count. To properly handle errors with this term, code must both handle exceptions and check theerrors
return value!
Example: Update the status of the post with id
of 1
to published
.
r.table("posts").get(1).update({"status": "published"}).run(conn)
Example: Update the status of all posts to published
.
r.table("posts").update({"status": "published"}).run(conn)
Example: Update the status of all the posts written by William.
r.table("posts").filter({"author": "William"}).update({"status": "published"}).run(conn)
Note that
filter
,get_all
and similar operations do not execute in an atomic fashion withupdate
. Read Consistency guarantees for more details. Also, see the example for conditional updates below for a solution usingbranch
in anupdate
clause.
Example: Increment the field view
of the post with id
of 1
. This query will throw an error if the field views
doesn’t exist.
r.table("posts").get(1).update({
"views": r.row["views"]+1
}).run(conn)
Example: Increment the field view
of the post with id
of 1
. If the field views
does not exist, it will be set to 0
.
r.table("posts").get(1).update({
"views": (r.row["views"]+1).default(0)
}).run(conn)
Example: Perform a conditional update.
If the post has more than 100 views, set the type
of a post to hot
, else set it to normal
.
r.table("posts").get(1).update(lambda post:
r.branch(
post["views"] > 100,
{"type": "hot"},
{"type": "normal"}
)
).run(conn)
Example: Update the field num_comments
with the result of a sub-query. Because this update is not atomic, you must pass the non_atomic
flag.
r.table("posts").get(1).update({
"num_comments": r.table("comments").filter({"id_post": 1}).count()
}, non_atomic=True).run(conn)
If you forget to specify the non_atomic
flag, you will get a ReqlRuntimeError
:
ReqlRuntimeError: Could not prove function deterministic. Maybe you want to use the non_atomic flag?
Example: Update the field num_comments
with a random value between 0 and 100. This update cannot be proven deterministic because of r.js
(and in fact is not), so you must pass the non_atomic
flag.
r.table("posts").get(1).update({
"num_comments": r.js("Math.floor(Math.random()*100)")
}, non_atomic=True).run(conn)
Example: Update the status of the post with id
of 1
using soft durability.
r.table("posts").get(1).update({status: "published"}, durability="soft").run(conn)
Example: Increment the field views
and return the values of the document before and after the update operation.
r.table("posts").get(1).update({
"views": r.row["views"]+1
}, return_changes=True).run(conn)
The result will now include a changes
field:
{
"deleted": 0,
"errors": 0,
"inserted": 0,
"changes": [
{
"new_val": {
"id": 1,
"author": "Julius_Caesar",
"title": "Commentarii de Bello Gallico",
"content": "Aleas jacta est",
"views": 207
},
"old_val": {
"id": 1,
"author": "Julius_Caesar",
"title": "Commentarii de Bello Gallico",
"content": "Aleas jacta est",
"views": 206
}
}
],
"replaced": 1,
"skipped": 0,
"unchanged": 0
}
Updating nested fields
The update
command supports RethinkDB’s nested field syntax to update subdocuments. Consider a user table with contact information in this format:
{
"id": 10001,
"name": "Bob Smith",
"contact": {
"phone": {
"work": "408-555-1212",
"home": "408-555-1213",
"cell": "408-555-1214"
},
"email": {
"work": "[email protected]",
"home": "[email protected]",
"other": "[email protected]"
},
"im": {
"skype": "Bob Smith",
"aim": "bobmoose",
"icq": "nobodyremembersicqnumbers"
}
},
"notes": [
{
"date": r.time(2014,1,1,'Z'),
"from": "John Doe",
"subject": "My name is even more boring than Bob's"
},
{
"date": r.time(2014,2,2,'Z'),
"from": "Bob Smith Sr",
"subject": "Happy Second of February"
}
]
}
Example: Update Bob Smith’s cell phone number.
r.table("users").get(10001).update(
{"contact": {"phone": {"cell": "408-555-4242"}}}
).run(conn)
Example: Add another note to Bob Smith’s record.
new_note = {
"date": r.now(),
"from": "Inigo Montoya",
"subject": "You killed my father"
}
r.table("users").get(10001).update(
{"notes": r.row["notes"].append(new_note)}
).run(conn)
This will fail if the notes
field does not exist in the document. To perform this as an “upsert” (update or insert), use the default command to ensure the field is initialized as an empty list.
r.table("users").get(10001).update(
{"notes": r.row["notes"].default([]).append(new_note)}
).run(conn)
Example: Send a note to every user with an ICQ number.
icq_note = {
"date": r.now(),
"from": "Admin",
"subject": "Welcome to the future"
}
r.table("users").filter(
r.row.has_fields({"contact": {"im": "icq"}})
).update(
{"notes": r.row["notes"].append(icq_note)}
).run(conn)
Example: Replace all of Bob’s IM records. Normally, update
will merge nested documents together; to replace the entire "im"
document, use the literal command.
r.table('users').get(10001).update(
{"contact": {"im": r.literal({"aim": "themoosemeister"})}}
).run(conn)
© RethinkDB contributors
Licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License.
https://rethinkdb.com/api/python/update/