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

Cannot query DynamoDB table with partition key only using QueryAsync #1898

Closed
lorisleitner opened this issue Aug 10, 2021 · 5 comments
Closed
Labels
bug This issue is a bug. dynamodb low-effort p2 This is a standard priority issue queued

Comments

@lorisleitner
Copy link

lorisleitner commented Aug 10, 2021

Description

I'm trying to query a DynamoDB table using the .NET SDK. I'm using DynamoDBContext.QueryAsync<>.
The data model looks like this:

[DynamoDBTable("prices")]
public class Price
{
    [DynamoDBHashKey("id")]
    public String Id { get; set; }

    [DynamoDBProperty("symbol")]
    public string Symbol { get; set; }

    [DynamoDBProperty("expdate")]
    public long ExpDate { get; set; }
}

Note that there isn't a sort key defined as the table does not have one.

When trying to query the table like this, I'm getting an InvalidOperationException
q = db.QueryAsync<Price>("ID");

System.InvalidOperationException: 'Must have one range key or a GSI index defined for the table prices'

Trying to query the table using FromQueryAsync will work:

var query = new QueryOperationConfig()
{
    KeyExpression = new Expression()
    {
        ExpressionStatement = "id = :id",
        ExpressionAttributeValues = new Dictionary<string, DynamoDBEntry>()
        {
            {":id", "ID" }
        }
    },
};

var q = db.FromQueryAsync<Price>(query);
...

I expect QueryAsync to work the same as FromQueryAsync.

Reproduction Steps

See above

Logs

StackTrace

   at Amazon.DynamoDBv2.DataModel.DynamoDBContext.ComposeQueryFilterHelper(DynamoDBFlatConfig currentConfig, Document hashKey, IEnumerable`1 conditions, ItemStorageConfig storageConfig, List`1& indexNames)
   at Amazon.DynamoDBv2.DataModel.DynamoDBContext.ComposeQueryFilter(DynamoDBFlatConfig currentConfig, Object hashKeyValue, IEnumerable`1 conditions, ItemStorageConfig storageConfig, List`1& indexNames)
   at Amazon.DynamoDBv2.DataModel.DynamoDBContext.ConvertQueryByValue[T](Object hashKeyValue, IEnumerable`1 conditions, DynamoDBOperationConfig operationConfig, ItemStorageConfig storageConfig)
   at Amazon.DynamoDBv2.DataModel.DynamoDBContext.QueryAsync[T](Object hashKeyValue, DynamoDBOperationConfig operationConfig)
   at ccctest.Program.<Main>d__0.MoveNext() in C:\Users\loris\source\repos\ccctest\ccctest\Program.cs:line 44

Environment

  • SDK Version: 3.7.0.50
  • Package Version: 3.7.0.50
  • OS Info: Windows 10
  • Build Environment: Visual Studio
  • Targeted .NET Platform: .NET Core 3.1

Resolution

I hope this is a real bug and not a misuse by me.


This is a 🐛 bug-report

@lorisleitner lorisleitner added bug This issue is a bug. needs-triage This issue or PR still needs to be triaged. labels Aug 10, 2021
@ashishdhingra
Copy link
Contributor

Reproducible using the following code:

using Amazon;
using Amazon.DynamoDBv2;
using Amazon.DynamoDBv2.DataModel;
using Amazon.DynamoDBv2.DocumentModel;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace DynamoDBQuery_Issue1898
{
    class Program
    {
        static void Main(string[] args)
        {
            RegionEndpoint regionEndpoint = RegionEndpoint.USEast1;
            AmazonDynamoDBClient amazonDynamoDBClient = new AmazonDynamoDBClient(regionEndpoint);
            DynamoDBContext dynamoDBContext = new DynamoDBContext(amazonDynamoDBClient);

            List<Price> prices = ExecuteQueryAsync(dynamoDBContext, "121").Result;
            //List<Price> prices = ExecuteFromQueryAsync(dynamoDBContext, "121").Result;

            foreach (var price in prices) Console.WriteLine(price);
        }

        private static async Task<List<Price>> ExecuteQueryAsync(DynamoDBContext dynamoDBContext, string id)
        {
            var query = dynamoDBContext.QueryAsync<Price>(id);

            var prices = new List<Price>();

            do
            {
                List<Price> nextSet = await query.GetNextSetAsync();
                prices.AddRange(nextSet);
            } while (!query.IsDone);

            return prices;
        }

        private static async Task<List<Price>> ExecuteFromQueryAsync(DynamoDBContext dynamoDBContext, string id)
        {
            var query = new QueryOperationConfig()
            {
                KeyExpression = new Expression()
                {
                    ExpressionStatement = "id = :id",
                    ExpressionAttributeValues = new Dictionary<string, DynamoDBEntry>()
                    {
                        {":id", id }
                    }
                }
            };


            var fromQueryResult = dynamoDBContext.FromQueryAsync<Price>(query);

            var prices = new List<Price>();

            do
            {
                List<Price> nextSet = await fromQueryResult.GetNextSetAsync();
                prices.AddRange(nextSet);
            } while (!fromQueryResult.IsDone);

            return prices;
        }
    }

    [DynamoDBTable("prices")]
    public class Price
    {
        [DynamoDBHashKey("id")]
        public String Id { get; set; }

        [DynamoDBProperty("symbol")]
        public string Symbol { get; set; }

        [DynamoDBProperty("expdate")]
        public long ExpDate { get; set; }

        public override string ToString()
        {
            return $"[Price] Id: {Id}, Symbol: {Symbol}, ExpDate: {ExpDate}";
        }
    }
}

@ashishdhingra ashishdhingra removed the needs-triage This issue or PR still needs to be triaged. label Aug 10, 2021
@MDanialSaleem
Copy link

According to the docs this is expected behavior and not a bug.

If your table has a simple primary key (partition key), you can't use the Query method. Instead, you can use the Load method and provide the partition key to retrieve the item.

@guilhermecaixeta
Copy link

And is it possible to query/load a table without pass the sort key? Because I tried in many ways and always return some error. Like

 "message": "Unable to convert range key value for property Timestamp",
    "stack_trace": [
      "at Amazon.DynamoDBv2.DataModel.DynamoDBContext.MakeKey(Object hashKey, Object rangeKey, ItemStorageConfig storageConfig, DynamoDBFlatConfig flatConfig) in D:\\JenkinsWorkspaces\\trebuchet-stage-release\\AWSDotNetPublic\\sdk\\src\\Services\\DynamoDBv2\\Custom\\DataModel\\ContextInternal.cs:line 971",

@ashishdhingra ashishdhingra added p2 This is a standard priority issue and removed A labels Nov 1, 2022
@bhoradc
Copy link

bhoradc commented Oct 4, 2024

Closing this issue as it is not a bug, but rather an expected behavior as previously discussed in the comment.

@bhoradc bhoradc closed this as completed Oct 4, 2024
Copy link

github-actions bot commented Oct 4, 2024

Comments on closed issues are hard for our team to see.
If you need more assistance, please either tag a team member or open a new issue that references this one.
If you wish to keep having a conversation with other community members under this issue feel free to do so.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug This issue is a bug. dynamodb low-effort p2 This is a standard priority issue queued
Projects
None yet
Development

No branches or pull requests

6 participants