Feature: Support format specifiers when using numbers in template for composite attributes
PaulJNewell77 opened this issue ยท 14 comments
This is a feature request to be able to specify how a number field is formatted (specifically, padding) when using it in a composite attribute. This is required in the case that a number field is used as (or part of) a string SK, to ensure that sorting is correct. For example, if you had a dayOfMonth
field which is a number, to use as an SK it would need to be formatted by zero-padding to two characters: 01
, 02
, 03
, ...etc. This could be achieved by supporting format specifiers in the template such as ${dayOfMonth:2:0}
.
Thanks for making these tickets, I am afk through next Monday but this one has a quick answer: there is an attribute property called "padding" that does this ๐
Ah, I couldn't find it in the docs so didn't realise you'd implemented it since I spotted it originally. I'll give it a try, thanks.
Hi, I've tried this feature (maybe not correctly ;)
My day attribute is defined as:
day: { type: 'number', required: true, padding: { length: 2, char: '0' } }
And in the primary index, the SK is defined as:
sk: {
field: 'SK',
casing: 'none',
template: '${day}',
composite: ['day'],
}
With this request:
counts.query.primary({ '2022-05' }).gte({ 9 }).go();
I get this error:
One or more parameter values were invalid: Condition parameter type does not match schema type
Logging the the response from .params()
gives:
{
TableName: 'pjn-dev-v2-omw-pso-be-sst-coreStatsTable',
ExpressionAttributeNames: { '#pk': 'PK', '#sk1': 'SK' },
ExpressionAttributeValues: { ':pk': 'COUNT#2022-05', ':sk1': 9 },
KeyConditionExpression: '#pk = :pk and #sk1 >= :sk1'
}
I think ':sk1'
should be '09'
.
Subsequent to the above I tried to up an update / add and the Key
in the params is set to { PK: 'COUNT#2022-05', SK: 9 }
. Once again I think the SK should be 09
. But I may be missing something on the schema configuration.
The issue here looks to be that you're using a number-type sort key: day
is a number and your sk is defined as '${day}'
. As a result padding can't be added because the number 09
reduces to just 9
. If you change your sort key to be a string (based on what you shared, changing day
to an attribute type "string" would do it), then it will save as "09"
. Here is a playground demonstrating this:
Thanks for the response. I have an existing table in a production system with large amounts of data, which will be hard to migrate, so changing the structure is not really an option. Also, I feel the most valid use case for padding is when the attribute (day
in this case) is a number and the sort key is a string. If they were both strings it would be possible to do whatever padding is desired outside of ElectroDb (as per this playground link, where the padding
is not needed). So yes, I do need to coerce the sort key to be a string, other than changing the type of the day
attribute - is there another way of doing this in ElectroDb?
@rcoundon Thank you for the nudge, I needed it, and I will have something this weekend ๐
@PaulJNewell77 @rcoundon give 2.8.0 a spin, please let me know if you have any issues at all!
I tried with 2.8.1, and afraid it still behaves the same for me. Maybe, I'm setting it up wrong? My day attribute is defined as:
day: { type: 'number', required: true, padding: { length: 2, char: '0' } }
And in the primary index, the SK is defined as:
sk: {
field: 'SK',
casing: 'none',
template: '${day}',
composite: ['day'],
}
Thanks
@PaulJNewell77 On your sk
definition try adding the property cast: 'string'
. It should look like this:
sk: {
field: 'SK',
casing: 'none',
cast: 'string',
template: '${day}',
composite: ['day'],
}
Here's a demonstration:
Thank you, Paul's on leave this week and was closer to the detail of this but from my perspective it looks good
Hi Ty, yes, the cast
on the SK is what I needed, thanks. This feature works for me. Hopefully will be useful to others - definitely worth adding to the docs. Otherwise happy for the issue to be closed - I'm sure you'll be relieved ๐