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

ExecuteStatementCommand in lib-dynamodb failing with lists #4703

Closed
3 tasks done
cpyle0819 opened this issue May 5, 2023 · 7 comments · Fixed by #5306
Closed
3 tasks done

ExecuteStatementCommand in lib-dynamodb failing with lists #4703

cpyle0819 opened this issue May 5, 2023 · 7 comments · Fixed by #5306
Assignees
Labels
bug This issue is a bug. p2 This is a standard priority issue pending-release This issue will be fixed by an approved PR that hasn't been released yet. queued This issues is on the AWS team's backlog

Comments

@cpyle0819
Copy link

cpyle0819 commented May 5, 2023

Checkboxes for prior research

Describe the bug

The ExecuteStatementCommand from lib-dynamodb is failing when given a list as a parameter.

SDK version number

@aws-sdk/client-dynamodb: "^3.210.0"

Which JavaScript Runtime is this issue in?

Node.js

Details of the browser/Node.js/ReactNative version

18.12.1

Reproduction Steps

import {
  DynamoDBDocumentClient,
  ExecuteStatementCommand,
} from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({});
const docClient = DynamoDBDocumentClient.from(client);

const command = new ExecuteStatementCommand({
  Statement: `INSERT INTO Coffees value {'varietal':?, 'profile':?}`,
  Parameters: ["arabica", ["chocolate", "floral"]],
});
await docClient.send(command);

Observed Behavior

TypeError: Cannot read properties of undefined (reading '0')
    at AttributeValue.visit (/Users/corepyle/Documents/teams/aws-doc-sdk-examples/javascriptv3/node_modules/@aws-sdk/client-dynamodb/dist-cjs/models/models_0.js:645:40)

Expected Behavior

Expected the parameters array to be able to handle an array parameter.

Possible Solution

No response

Additional Information/Context

Working version with the base client:

import { ExecuteStatementCommand, DynamoDBClient } from "@aws-sdk/client-dynamodb";

const client = new DynamoDBClient({});

const command = new ExecuteStatementCommand({
  Statement: `INSERT INTO Coffees value {'varietal':?, 'profile':?}`,
  Parameters: [{ S: "arabica" }, { L: [{ S: "chocolate" }, { S: "floral" }] }],
});
await client.send(command);
@cpyle0819 cpyle0819 added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels May 5, 2023
@RanVaknin RanVaknin self-assigned this May 5, 2023
@RanVaknin
Copy link
Contributor

Hi @cpyle0819 ,

You are importing ExecuteStatementCommand from lib-dynamodb, but this is an import from the client-dynamodb package.

As far as I can tell, this command is a low level command to interact with dynamo using PartiQL.
Instead, lib-dynamodb would have PutCommand that would be an abstraction on top of this INSERT command.

Please check out this doc page

So in your case it would look something like:

import { DynamoDBClient } from "@aws-sdk/client-dynamodb";
import { DynamoDBDocumentClient, PutCommand } from "@aws-sdk/lib-dynamodb";

const client = new DynamoDBClient({ region: "us-east-1" });
const docClient = DynamoDBDocumentClient.from(client);


try {
    await docClient.send(new PutCommand({
        TableName: "Coffees",
        Item: {
            'varietal': "arabica",
            'profile': ["chocolate", "floral"]
        }
    }));
    console.log("Item inserted successfully.");  
} catch (error) {
    console.error(error);
}

Let me know if you have any other questions!
Thanks,
Ran~

@RanVaknin RanVaknin added response-requested Waiting on additional info and feedback. Will move to \"closing-soon\" in 7 days. p3 This is a minor priority issue and removed needs-triage This issue or PR still needs to be triaged. labels May 12, 2023
@cpyle0819
Copy link
Author

Hey, Ran. lib-dynamodb exports the ExecuteStatementCommand so data attribute types can be avoided. It sounds like you're telling me not to use that command from lib-dynamodb. It's a documented part of the library. Is that wrong?

@github-actions github-actions bot removed the response-requested Waiting on additional info and feedback. Will move to \"closing-soon\" in 7 days. label May 13, 2023
@RanVaknin
Copy link
Contributor

Hi @cpyle0819 ,

I totally missed that part. Partly because we don't have an example for it anywhere!

I'm able to reproduce the bug with the provided code and confirm that the serialization fails when trying to insert an array of arrays.

Will add to backlog.
Thanks,
Ran~

@RanVaknin RanVaknin added p2 This is a standard priority issue queued This issues is on the AWS team's backlog and removed p3 This is a minor priority issue labels May 14, 2023
@samuel-bach
Copy link

Same error also gets thrown for objects:

const command = new ExecuteStatementCommand({
  Statement: `INSERT INTO Coffees value {'varietal':?, 'profile':?}`,
  Parameters: ["arabica", { foo: "bar"}],
});

@kitsunde
Copy link

kitsunde commented Jul 26, 2023

@RanVaknin Could the typescript defs be fixed first since I am assuming this will take some time? ExecuteStatementCommand accepts NativeAttributeValue because of: https://github.com/aws/aws-sdk-js-v3/blob/main/packages/util-dynamodb/src/models.ts#L15 but it doesn't seem to actually handle {foo: 'bar'} as a value.

What seem to be happening is a parameter:

{foo: 'bar'}

becomes

{ foo: {S: 'bar'} }

but if you nest it:

{ inner: {foo: 'bar'} }

It understands the inner parts just fine:

{ inner: { M: { foo: { S: 'bar' } } } }

Effectively using the document client with PartiQL becomes not practical when dealing with non-scalar values.

@kitsunde
Copy link

In case anyone else runs into this, you'll want to import marshall from util-dynamodb and use call the regular dynamodb client instead.

To get this working:

Same error also gets thrown for objects:

const command = new ExecuteStatementCommand({
  Statement: `INSERT INTO Coffees value {'varietal':?, 'profile':?}`,
  Parameters: ["arabica", { foo: "bar"}],
});

Do this:

const { DynamoDBClient, ExecuteStatementCommand } = require('@aws-sdk/client-dynamodb');
const { marshall } = require('@aws-sdk/util-dynamodb');
const client = new DynamoDBClient({});

const command = new ExecuteStatementCommand({
  Statement: `INSERT INTO Coffees value {'varietal':?, 'profile':?}`,
  Parameters: marshall([
    "arabica",
    { foo: "bar"}
  ]),
});

await client.send(statement);

@github-actions
Copy link

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs and link to relevant comments in this thread.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug This issue is a bug. p2 This is a standard priority issue pending-release This issue will be fixed by an approved PR that hasn't been released yet. queued This issues is on the AWS team's backlog
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants