Reputation: 469
I have data structure like this in my rethinkdb:
{
"id":"123",
"otherId":"asd", <== based on this
"list": [
{
"id":"a",
"list_id":"1", <== and based on this
"status":"available" <== update this
},
{
"id":"b",
"list_id":"2",
"status":"available"
},
{
"id":"c",
"list_id":"3",
"status":"available"
},
{
"id":"d",
"list_id":"4",
"status":"available"
}
]
}
If I want to update status for list_id = 1, how do I do in python?
I tried to do it like this:
r.db('mydb').table('mytable').filter(r.row['Otherid'].eq("asd"))['list'].nth(0).default([]).filter(lambda doc: doc['list_id'] == "1").nth(0).default([]).update({"status":"offline"}).run()
But it gets me error rethinkdb.errors.ReqlQueryLogicError: Expected type SELECTION but found DATUM
UPDATE
I can't query using id (primary key) because data is not given.
I also tried this way:
currentData = r.db('myDb').table('myTable') \
.filter(r.row['otherId'].eq("asd"))['list'].nth(0).default([]) \
.filter(lambda doc: doc['list_id'] == "1").run(con, time_format='raw')
currentData["status"] = "offline"
r.db('mydb').table('mytable').filter(r.row['otherId'].eq("asd"))['list'].nth(0).default([]) \
.update(lambda row: row.merge({'list': row['list'].map(lambda row2: r.branch(row2['list_id'].eq("1"), currentData, row2))})) \
.run(con, time_format='raw')
But it appends the new data instead of udpdate
Thank you...
Upvotes: 1
Views: 130
Reputation: 2563
You need to use map()
and merge()
. Something like this:
r.table("mytable") \
.filter(r.row['otherId'] == "asd") \
.update({
"list": r.row["list"].map(lambda item: item.merge(
r.branch(item["list_id"] == "1", {"status": "offline"}, {})))
})
I also suggest to use indices in your table and get_all()
instead of filter()
.
If list_id
or id
is always unique in the array under the list
key, you could also just use an object (keyed by the unique id) instead of an array and make your life easier.
Upvotes: 2