pplu / aws-sdk-perl

A community AWS SDK for Perl Programmers
Other
171 stars 94 forks source link

Can't call method "does" on unblessed reference when trying to use DynamoDB::GetItem #40

Closed vivus-ignis closed 9 years ago

vivus-ignis commented 9 years ago

Hello,

I have this fragment of code

use Paws;
use Paws::DynamoDB::Key;
use Paws::DynamoDB::AttributeValue;

my $dynamo_api = Paws->service('DynamoDB', region => 'eu-west-1');
my $res = $dynamo_api->GetItem(
  TableName            => "platform_config",
  ProjectionExpression => 'value',
  Key                  =>
    Paws::DynamoDB::Key->new(
      Map => {
         name => Paws::DynamoDB::AttributeValue->new(
           S => 'celery.broker_url'
         )
      }
    )
);

The structure of my dynamodb table is simple: primary hash key is called "name" (type string). When I run this code, the result is this error: Can't call method "does" on unblessed reference at /vagrant/local/lib/perl5/Paws/Net/JsonCaller.pm line 34. Perl v5.22.0, Paws-0.13.

Thank you very much for any suggestions.

pplu commented 9 years ago

Hi!

I think I see what's going on. You shouldn't be constructing those intermediate objects that are getting passed to GetItem. Just pass in ArrayRefs and HashRefs, and those will be coerced into the appropiate intermediate objects:

What you're trying to do should look like:

GetItem(... Key => { 'KeyName' => { S => 'celery.broker_url } })

Paws will be creating the Paws::DynamoDB::Key object, and initializing it's Map for you in the background :).

Don't hesitate to give feedback about the rough edges around documentation that led you to try to make those intermediate objects.

Please tell me if you got it to work

vivus-ignis commented 9 years ago

Hello,

got back to the task again. So I tried with this code -- but the error message is exactly the same

  my $res = $dynamo_api->GetItem(
    TableName            => 'platform_config',
    ProjectionExpression => 'value',
    Key                  => {
      'name' => { S => 'celery.broker_url' }
    }
  );

Thank you very much for your attention!

pplu commented 9 years ago

Hi, I'll take a look at it.

It would be helpful if you send me a "Test DyanmoDB" script that creates a table, puts and gets a value to reproduce the error. Note: it doesn't have to be a Perl/Paws script. It can invoke the aws cli to create the table, for example :)

vivus-ignis commented 9 years ago

Hello again, I've put the test script and the files needed for the test here: https://github.com/vivus-ignis/paws-dynamodb-issue-test

Thank you.

pplu commented 9 years ago

Thanks for the script! That helps a lot!

pplu commented 9 years ago

Fixed! But we need some testing :)

The thing is that the SDK was not handling StrToObj in JSON-style APIs, since we had support for that type of mappings in other APIs, that was easy to fix (and test so we don't get regressions).

After that, it started to get interesting: the problem started to be in the response. botocore doesn't define where to get the "key" value from the returning AttributeMap. Once fixed, it results that the AttributeMaps are really not a mapping of a string to an object, they're more of an object-to-object mapping (a hash were the keys are objects, instead of strings).

I've tried to map the object in the key as an "easy to get" key, converting the object that DynamoDB returns into a string. If the key is { S => 'celery_broker' }, the key for the item will be S#celery_broker, as it looks like the keys are one element hashes. Do you think it's easy / intuitive enough?

Please try out the changes in a branch named "issue-40" (https://github.com/pplu/aws-sdk-perl/tree/issue-40)

pplu commented 9 years ago

Ups. Never mind my last message. I misunderstood how DynamoDB is passing its results back in the Map. I'm preparing another fix.

pplu commented 9 years ago

Now I've got it... The fix is in the same branch "issue-40" (https://github.com/pplu/aws-sdk-perl/tree/issue-40).

The problem was that Maps responses are handled differently for different types of API types (JSON/XML). I've moved the code for handling XML Map types to the XMLResponse classes, and the code for JSON Maps into JSONResponse classes.

Can you try out with this branch?

pplu commented 9 years ago

Paws 0.14 is on CPAN with the fix for this issue. Cheers! (and thanks!)

vivus-ignis commented 9 years ago

Sorry for a slow reply -- just got back from a vacation. 0.14 works well. I had just to remove ProjectionExpression (our tables have an item attribute called 'value' -- which happens to be a reserved word somewhere in Paws or one of the underlying modules). Anyways, many thanks for your help!