🌳
DynamoDB のデータ形式からJSON形式への変換
DynamoDB のデータ形式からJSON形式への変換
DynamoDBからとってきたデータが,予測していたデータ形式と異なり扱いづらいのでシンプルなJSON形式に整形し直すことができるdynamodb-data-marshallerというライブラリを使用したときに引っかかったので記録する.
DynamoDBからデータとフェッチしてきたときに期待されるデータ形式は以下のようになっていてほしい
{
id: '123-ss',
name: 'shima',
filepass: 'Sample/sample2.mp3',
memo: 'memomemo'
}
しかしDynamoDBのデータ形式がどのようになっているかというと
{
id: { S: '123-ss' },
name: { S: 'shima' },
filepass: { S: 'Sample/sample2.mp3' },
memo: { S: 'memomemo' }
}
このようにネストされたデータ形式になっている.これによってとても扱いにくくなる.
これをmarchellerを使用することで上のデータ形式にリバースすることができる.
扱い方は簡単で
import { marshallItem, unmarshallItem } from '@aws/dynamodb-data-marshaller';
import { UserDataSchema } from '../Schema/User'
const params = {
Statement: 'SELECT * FROM ' + 'Sound' + ' where id=?',
Parameters: [{ S: id }],
};
const res = await this.client.send(new ExecuteStatementCommand(params));
if (res.Items?.length != 1) {
throw new Error('取得できませんでした');
}
unmarshallItem(UserDataSchema, res.Items[0]);
export const UserDataSchema = {
id: { type: 'String' },
name: { type: 'String' },
filepass: { type: 'String' },
memo: { type: 'String' },
};
このようにできるはず.だったが
Type '{ type: string; }' is not assignable to type 'SchemaType'.
Property 'members' is missing in type '{ type: string; }' but required in type 'TupleType<any[]>'
みたいなエラーが出ている.一旦ライブラリの中身を覗いてみる
export declare function unmarshallItem<T = {
[key: string]: any;
}>(schema: Schema, input: AttributeMap, valueConstructor?: ZeroArgumentsConstructor<T>): T;
Schema というデータ形式と一致していないようだ
export interface Schema {
[key: string]: SchemaType;
}
Schema というインターフェイスに合致させる必要があり,このSchema interface自体はkeyを持ちvalueとして,SchemaTypeというinterfaceに一致させる必要がある
このSchemaType自体は
export declare type SchemaType = AnyType | BinaryType | BooleanType | CustomType<any> | CollectionType | DateType | DocumentType<any> | HashType | ListType | MapType | NullType | NumberType | SetType | StringType | TupleType;
で
今回はStringTypeだけを使いたいので,
StringTypeの中を覗くと
export interface StringType extends BaseType<string>, KeyableType {
type: 'String';
}
あれ,あってそうなのに...
よくよく自分で定義したSchemaに出ているエラーを見てみると
UserDataSchemaは
const SoundSchema: {
id: {
type: string;
};
name: {
type: string;
};
filepass: {
type: string;
......
みたいに解釈されてしまっている.
しかしStringTypeでは'StringType'という文字列形式で解釈されるべき対処法がとりあえず直接引数に書き込むことしかできなくて悲しいがとりあえずこれでエラー自体あ解消できる
unmarshallItem(
{
id: { type: 'String' },
name: { type: 'String' },
filepass: { type: 'String' },
memo: { type: 'String' },
id: { type: 'String' },
},
res.Items[0],
);
Discussion
const schema: { [key: string]: SchemaType } = {...}
のように型注釈を付けてあげたら上手く行きました。