Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conditional update array element #684

Open
mzientkowski opened this issue Sep 25, 2023 · 1 comment
Open

Conditional update array element #684

mzientkowski opened this issue Sep 25, 2023 · 1 comment

Comments

@mzientkowski
Copy link

Hi, i'm using latest version (v 3.9.0) and I try to update element in array with condition.
Here is example:

class Test
  include Dynamoid::Document

  table name: :test, key: :id, capacity_mode: :on_demand

  field :test_array, :array, of: :string
end
Test.find(id).update(if: { 'test_array[0]': 'test' }) do |t|
  t.set('test_array[0]': 'test_pass')
end

it doesn't work and ends with an error:

[Aws::DynamoDB::Client 400 0.211219 0 retries] update_item(table_name:"test",key:{"id"=>{s:"1"}},attribute_updates:{"updated_at"=>{action:"PUT",value:{s:"2023-09-25T07:19:01+00:00"}},"test_array[0]"=>{action:"PUT",value:{s:"test_pass"}}},expected:{"test_array[0]"=>{value:{s:"test"}}},return_values:"ALL_NEW") Aws::DynamoDB::Errors::ConditionalCheckFailedException The conditional request failed

I managed to achieve this using low-level methods

Dynamoid.adapter.client.update_item(
  {
    table_name: 'test',
    key: {
      "id": id
    },
    expression_attribute_values: {
      ":new_array_elem" => 'test_pass',
      ":prev_array_elem" => 'test',
    },
    condition_expression: "test_array[0] = :prev_array_elem",
    update_expression: "SET test_array[0] = :new_array_elem",
    return_values: "ALL_NEW"
  }
)

And it works:

[Aws::DynamoDB::Client 200 0.158401 0 retries] update_item(table_name:"test",key:{"id"=>{s:"1"}},expression_attribute_values:{":new_array_elem"=>{s:"test_pass"},":prev_array_elem"=>{s:"test"}},condition_expression:"test_array[0] = :prev_array_elem",update_expression:"SET test_array[0] = :new_array_elem",return_values:"ALL_NEW")

it would be nice if it also worked from Dynamioid level.
Or maybe i'm doing something wrong, so please provide working example ;) Thanks

@andrykonchin
Copy link
Member

Dynamoid doesn't support yet conditions on/updating of nested attributes or array elements.

But migration from deprecated attributes to the new expression-like ones (e.g. mentioned in the example above condition_expression and update_expression) is in progress. I've stated with #where method (#655) and hopefully will migrate all the public methods till the next release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants