tywalch/electrodb

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.

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?

@tywalch - sorry to nudge, any thoughts on this?

@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

@rcoundon tagging you as well

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 ๐Ÿ˜„