HENNGE / aiodynamo

Asynchronous, fast, pythonic DynamoDB Client
https://aiodynamo.readthedocs.io/
Other
69 stars 20 forks source link

BatchGetRequest projection doesn't work #188

Closed pablobd closed 4 days ago

pablobd commented 1 week ago

I am using Python 3.10.13 and aiodynamo==24.1

I am trying to a client.batch_get.

r = await client.batch_get(request)

Request is the following:

request = {
            "ml_integ.feature_engineering.amount_binned__counterparty_name": BatchGetRequest(
                keys=[
                    {
                        "_feature_store_internal__primary_keys": '["[-50, 0]", "97e8256663aac93993d112a3958658de72240569"]'
                    }
                ],
                projection="_feature_store_internal__primary_keys,subCategoryRulesCounterAC,subCategoryUserCounterAC,ruleUserConfusionMetricsCounterAC",
            )
}

I am getting the following error,

.pyenv/versions/3.10.13/lib/python3.10/site-packages/aiodynamo/models.py", line 370, in to_request_payload
    payload["ProjectionExpression"] = self.projection.encode(params)
TypeError: encode() argument 'encoding' must be str, not Parameters

The request key (which works well) using boto3 sync client is the following:

{
    "ml_integ.feature_engineering.amount_binned__counterparty_name": {
        "Keys": [
            {
                "_feature_store_internal__primary_keys": '["[-50, 0]", "97e8256663aac93993d112a3958658de72240569"]'
            }
        ],
        "ExpressionAttributeNames": {"#K": "_feature_store_internal__primary_keys"},
        "ProjectionExpression": "#K,subCategoryRulesCounterAC,subCategoryUserCounterAC,ruleUserConfusionMetricsCounterAC",
    }
}

Note that the ExpressionAttributeNames is necessary because it starts with underscore and having it directly in ProjectionExpression throws an error.

ojii commented 1 week ago

As the documentation of BatchGetRequest shows, the projection field should be an instance of ProjectionExpression. These get constructed using the F class and it handles parametrizing the paths for you.

Your request should probably be something like this:

request = {
            "ml_integ.feature_engineering.amount_binned__counterparty_name": BatchGetRequest(
                keys=[
                    {
                        "_feature_store_internal__primary_keys": '["[-50, 0]", "97e8256663aac93993d112a3958658de72240569"]'
                    }
                ],
                projection=F("_feature_store_internal__primary_keys") & F("subCategoryRulesCounterAC") & F("subCategoryUserCounterAC") & F("ruleUserConfusionMetricsCounterAC"),
            )
}