Search code examples
pythonarraysdatabaserethinkdbrethinkdb-python

Python / Rethink DB Append Nested Array


I am trying to use python to add elements nested array in a RethinkDB. I was able to edit the "vendors" list by using the following code. But now I want to append the array 1 nest deeper. The expected results should add an addition set of price data under an existing vendor (See Expected Results).

Working code to add vendor

newData = {vendor: [{"salePrice": price, "available": available, "timestamp": r.now()}]}
r.table('UPC').get(uid).update({"vendors": r.row["vendors"].append(newData)}).run(conn)

DB Schema:

"id": "049a9b69-3378-4e67-98ce-7c76c4feb2f7" ,
"name": "5-Year Protection Plan - Geek Squad" ,
"upc": "400010179442" ,
"vendors": [
    {
        "Best Buy": [
            {
                 "available": false ,
                 "salePrice": 309.99 ,
                 "timestamp": Wed Jul 12 2023 12:09:58 GMT+00:00
            }
        ]
    } ,
    {
        "Target": [
            {
                 "available": false ,
                 "salePrice": 309.99 ,
                 "timestamp": Wed Jul 12 2023 12:10:22 GMT+00:00
            }
        ]
    }
]

Expected Results: DB Schema:

"id": "049a9b69-3378-4e67-98ce-7c76c4feb2f7" ,
"name": "5-Year Protection Plan - Geek Squad" ,
"upc": "400010179442" ,
"vendors": [
    {
        "Best Buy": [
            {
                 "available": false ,
                 "salePrice": 309.99 ,
                 "timestamp": Wed Jul 12 2023 12:09:58 GMT+00:00
            }
        ]
    } ,
    {
        "Target": [
            {
                 "available": false ,
                 "salePrice": 309.99 ,
                 "timestamp": Wed Jul 12 2023 12:10:22 GMT+00:00
            }
            {
                 "available": false ,
                 "salePrice": 307.96 ,
                 "timestamp": Wed Jul 13 2023 12:10:22 GMT+00:00
            }
        ]
    }
]

Bellow is some things I have tried:

Attempt #1

newData = {"salePrice": price, "available": available, "timestamp": r.now()}
r.table('UPC').get(uid).update({"vendors": r.row["vendors"][vendor].append(newData)}).run(conn)

Attempt #2

newData = {"salePrice": price, "available": available, "timestamp": r.now()}
r.table('UPC').get(uid).update({"vendors": {vendor:[r.row[vendor].append(newData)]}}).run(conn)

Attempt #3

newData = {"salePrice": price, "available": available, "timestamp": r.now()}
r.table('UPC').get(uid).update({"vendors": {vendor: r.row[vendor].append(newData)}}).run(conn)

With what I have tried I usually get an error response of

'first_error': 'No attribute `Target` in object

Solution

  • I feel like this answer is a bit of a work around, but it works. It gets the current values of the vendor (Best Buy or Target), modifies those values locally then uses a merge to update the old with the new.

        newData = {"salePrice": price, "available": available, "timestamp": r.now()}
        results = r.table('UPC').get(uid)['vendors'][vendor].run(conn)
        results[0].append(newData)
        updateData = {vendor: results[0]}
        ret = r.table('UPC').get(uid).update({"vendors": r.row["vendors"].merge(updateData)}).run(conn)