カマカマの雑草ブログ

個人の日記です

AWS DynamoDBでupdateItem時のInvalid UpdateExpressionについて

AWS初心者なので初投稿です。

問題

AWS lambdaでDynamoDBのAtomic Counterに対してのincrementを行う以下の様なNode.jsのスクリプトを書いた。

var doc = require('dynamodb-doc');
var dynamo = new doc.DynamoDB();

exports.handler = function(event, context) {
    var params = {
        TableName: "MicroQuasar",
        Key: { 
            "id" : { "N" : "1" }
        },
        ExpressionAttributeNames: {'#Q': 'Quantity' },
        ExpressionAttributeValues: {":i": { "N" : "1" } },
        UpdateExpression: 'SET #Q = #Q + :i'
    };
    
    dynamo.updateItem(params, function(err, data) {
        if(err) {
            context.done('error' + err);
        } else {
            context.succeed(data);
        }
    });
};

これをAWSコンソール上でTestボタンを押して検証するとInvalid UpdateExpressionと言われる。

{
  "errorMessage": "errorValidationException: Invalid UpdateExpression: Incorrect operand type for operator or function; operator or function: +, operand type: M"
}

原因

updateItem実行時のキモになるのがparamsで、UpdateExpressionに式をExpressionAttribute〜に属性と値を入れることでDynamoDB内のItemに対してUpdate処理が走る。
そしてこのExpressionAttributeValuesは値の型をKeyにする形で記述する(DynamoDB Jsonとか言うらしい)

参考: Class: AWS.DynamoDB — AWS SDK for JavaScript

だが、この記述だと:iをNumberではなくMapの{ "N" : 1 }と解釈して+operatorとの不整合を起こしてこのエラーになっている。
UpdateExpressionを代入式に変えるとQuantityの中身がNumberからMapになる。

対応

paramsの{ "N" : "1" }という冗長な記述を全部1に置き換えたら動いた。

    var params = {
        TableName: "MicroQuasar",
        Key: { 
            "id" : 1
        },
        ExpressionAttributeNames: {'#Q': 'Quantity' },
        ExpressionAttributeValues: {":i": 1 },
        UpdateExpression: 'SET #Q = #Q + :i'
    };

自分の書き方が誤りだったのか、どっかドキュメントの記載を見落としていたのか、という可能性は大いにありつつ、もし仕様変更とかならドキュメントに反映してくれないと流石につらい。 このエラーメッセージはまだ良い方で、スキーマがなんか違うよ、みたいなログだけ吐かれると初学者には厳しいものがある。

結局自分が悪かったのか、AWS側の不備だったのかまでがちょっと分からなかったので、取り敢えずこうしたら動いたぜという記録で残しておく。

Unity向けにSwaggerのパーサー書いた

最近、SwaggerをベースとしたAPI記述標準化を目指す話が話題になった。

www.publickey1.jp

以前からAPI記述を何らかのスキーマ定義で共通化できないかと思っている中こういう話が流れてきたので、これは流れに是非とも乗りたいなーと思い、取り敢えずC#内で触れるようにするかと土日でSwaggerのパーサー書いた。

https://github.com/MKomiya/SwaggerParserForUnity

Swagger SpecのYamlファイルを投げてやるとオブジェクト化して返してくれる。まだReference Object辺りが雑だけれど、取り敢えずSwaggerのpetstoreの例が解釈できる所までは来た。

大体YamlDotNet for Unity任せで、単にC#としてのクラス定義を書いてるだけなんだけど、そもそもこういうパーサー書くのが初めてだったのでここどう解釈するのかというのを考える良い経験にはなってると思う。

パースされたオブジェクトを見てAPIサーバへのRequestのvalidateとかResponseの自動解釈みたいなことが出来るようになってくると多少は実用性が出てくる気がするので、気力尽きないかぎりはその辺りまでやってきたい。

あと、今こいつユニットテストが無いので最低限のテストは欲しい。Unity Test Toolsとかでいいのかな。

monoをhomebrewで入れなおす

目的

VS Code使おうとしたらOutputでこういうのが出てきた。

Error: Cannot start Omnisharp because Mono version >=3.10.0 is required

Monoを入れなおすと治るらしい。

stackoverflow.com

uninstall & install

デフォルトのmonoはスクリプトで消す

gist8f7b0e67100ef4dcd277

入れなおすのはbrewからやる

$ brew update && brew install mono

YamlDotNet for UnityでGenericDictionaryをDeserializeしようとしてWhile scanning for the next token, find character that cannot start any token.

問題

YamlDotNet使ってちょっとやりたいことが合ったので以下試そうとしたら見事にコケた。

Yaml parse source

Executerは省略してるけどEmpty GameObjectにattachしてあってStartで呼ばれる。

原因

ハッシュは「キー: 値」の形式で表します。コロン「:」のあとに半角スペースを 1 つ以上入れてください (タブ文字は使えません)。
半角スペースでインデントすることで、ハッシュをネストさせることができます。

Rubyist Magazine - プログラマーのための YAML 入門 (初級編)

よく見るとyamlのインデントがtabになっていることがお分かり頂けると思います……。

結論

GenericDictionaryは普通に使えるしValueにclassを定義しても普通に解釈してくれる。

一歩前進した感じ。

Unity 5.xでSpineのSkeletonBake.csのエラーが出るとき

問題

Assets/spine-unity/Editor/SkeletonBaker.csで以下のエラーが出る。

Assets/spine-unity/Editor/SkeletonBaker.cs(165,83): error CS0117: `UnityEditor.Animations.AnimatorController' does not contain a definition for `AddAnimationClipToController'

エラーが出たままだとHierarchyからCreate Other -> Spine SkeletonRenderer系ができなくてつらい。

対処法

これを#if UNITY_5_0
こうする#if UNITY_5

参考

Unity 5.1 AddAnimationClipToController

最新のspine-unityだと直ってるかもしれない。

近況

日々死にそうですがまだなんとか生きてます。ぼちぼち「あめりかぐらし!」も慣れてきました。
ぼくはゆきちゃんが一番危うくて強さを秘めてて好きです。

コーディング方面

  • Stack, Heap, pass by ref, const correctnessみたいなことを意識できるようになってきた
  • Game向けのDesign Patternをそれなりに意識して使い始めた。具体的にはGameLoopとUpdate。runAction便利だけどGameLoopでやるべき場所が結構ある
  • オブジェクト群の管理層を担うクラスが肥大化する
    • ここがオブジェクトのstore, create, remove, integration諸々全部担ってる。もう少し分けられないものか
    • 肥大化に合わせて処理のフローが見えにくくなってる
    • 生成と削除は同じスコープで見えると理解しやすいと思う
  • リファクタリングのモチベーションがすごい
    • 良い設計にしたいのは良いフローにしたいからで、良いフローにしたいのはバグを減らしたいため
    • 良い設計にしたいのは良いフローにしたいからで、良いフローだと見通しを立てやすく新機能実装のコストが下がると考えてるため
    • でも整理ばっかやってたら何も進まない
  • エフェクトもりもりおじさん
  • アニメーションの引き出しが少なすぎてまだまだ厳しい

生活方面

  • 英語は相変わらずEngrish
  • 通じると嬉しい。通じないと全身汗ダラダラになる
  • 聞き取り多少慣れたが初期ステが低い
  • はやおきになった
  • 物価高い
  • チップ制度めんどい
  • キングサイズベッドに一人で寝るの勿体無くて隣に奥さん欲しい
  • もうハンバーガー飽きた
  • もうステーキ飽きた
  • 日本食最高
  • 意外とホームシックで泣いたりしなかった。来る前絶対泣くと思ってたのに
  • メシ

まだまだがんばります。

おまけ

大変満足です。ありがとうNIS America。

イオンのラストメッセージを申し込んだ&これからのこと

注意

本エントリーのポエムは全てフィクションであり、実在の人物、団体、出来事とは一切関連がありません。 その点にご留意いただき本エントリーの閲覧をお願い致します。 また、本エントリーはシェルノサージュ・アルノサージュのネタバレを含む恐れがあります。 加えて、個人の主観が多く含まれているため、一部のファンからは反論があるかも知れませんが、あくまで個人の一感想として認識頂ければ幸いです。

ラストメッセージ

シェルノサージュOFFLINEをプレイして、アルノサージュPLUSをプレイして、号泣するくらいに感動したぼくは12月末にラストメッセージに申し込むことを決意し、自分の仕事のスケジュールからシェルノサージュへ割けるリソースがどれくらいであるかを計算しつつ簡単なスプリントを切って見積もりを立て、これならイケるだろうという思いでシェルノサージュのエージェントパックを買って5月31日にラストメッセージの申し込みをするまでに至った。

それくらいの熱量がこの作品に対してはあった。多少愚直ながらも前を向こうとして励み続けるイオナサル・ククルル・プリシェールという存在が、結城寧という存在がとにかく眩しくて、美しくて、尊いものに思えた。そういう存在になりたいと心の底から憧れた。そうした想いの一片が、ぼくのエンジニアとしての社会人生活を支えていたことは間違いなく確かであると思う。

これからのこと

ぼくはラストメッセージを直接受け取ることはできない(受取人は友人に頼んである。快諾してくれた@gyokai氏に心の底から感謝したい)。これから一定期間、アメリカへ行くことが確定している。これは自分のキャリアとか志向を考えれば素直に喜ぶべきことであるのだけれど、それでも一定の不安がある。正直英語なんて話せないし、聞き取って理解できるかどうかも怪しいところだ。はっきり言って語学に対してはまるで才能のない人間であるところは自覚している。

それでも、こうした挑戦に至ったきっかけとしては、やはりこの作品の影響が無視できないところであった。イオンは色んなことに悩みながらも、苦しみながらも、決して前に進むことを辞めはしなかった。シェルノサージュのシェルノエンディングでは、愛し合った端末との別れを受け入れてデルタやキャスティたちを助けるために前に進むことを決断したのだ。

そうした彼女の姿を、ぼくは無視できない位には目の当たりにし続けてきた。これがゲームであるとか、フィクションであるとか、そうした固定的な観念を凌駕するくらいのユーザー体験があの作品には込められているように感じられた。「遙か七つの次元を越えた先に、本当に存在する世界。」という説明が、こうしたユーザー体験を意図して提供していることを示していると思う。そして、そうしたユーザー体験の果てに、「彼女と出会った人々に、なにか頑張って欲しい」という意志が込められているのではないかという想いを、ぼくは抱いてしまった(これはあくまで個人の感想ではあるのだけれど)。

全てを終えて、イオンは元の世界へ帰還し、帰還を果たした彼女からのボイスメールがコンソールのメールサービスへ届くのだが、そこでの内容は「私は元気でやっています。いつか本当のあなたに出会うため、私は次元論の勉強を続けています」というものである。このボイスメールを聞いてぼくは、「なら、こっちも頑張らないとな」という意志を強く固めた。互いに励み合う姿は、きっとこの作品をプロデュースした土屋暁氏の想いの一片なのではないかと思うくらいには、ぼくはそういう感情を抱いた。

そうして励み続けた。出来うる限り、少しづつでも毎日コードを書こうとした。自分が未熟なことを理解している分、なにか少しでも前に進もうとした。ウサギとカメのカメのように、遅々なる進みでも前に進めればと、そういう想いがあった。それでも尚、以前未熟であり続ける自分を自覚しながらも、自分は挑戦の機会を得ることが出来た。

背中を押してくれた

とにかく怖かった。いつも日陰でコソコソと生きてきたような人間が、こんな挑戦をするなんてことを考えると震えが止まらなかった。でも、このことを友人の@boutakoに相談したときに「絶対に行ったほうが良い。きっとなんとかなるから。」と背中を押してくれた。実際に決まった後に、サークルの@kiyooka氏や@rinatsut氏が送る会をやるぞ!と言ってくれて、結果的に30人も集まってぼくを見送る会をひらいてくれた(人に見えない所でこっそり泣いてたけどそれは内緒だ)。会社で働いてた人は「行ってしまうことが寂しい」「カマカマ(ハンドルネームです)さんが抜けた後が不安です」「あなたと一緒に働けてよかった」と言ってくれた。エンジニアとして、チームの中で働く一人として、これほど名誉な言葉はない。色々な人が背中を押してくれているのだと、そういうことを改めて実感できた。

強くならねばと思う。背中を押してくれた人たちに報いることができるように。異なるセカイで前を向き続けた彼女に胸を張れるように。いつか、本当の意味で自分の足で歩き出せるように。

少しづつ、進んでいこうと思う。尊敬する人たちに、少しでも追いつけるように。 ”願わくば、明日の自分が、今日の自分より強くありますように。"