内容
yasutomo.hatenablog.com
- 上記ブログでAzure Storage TableにPHPからアクセスしたときにハマったポイントをまとめたメモ
処理概要
- CSVから読み込んだデータをAzure Storage Tableに保持
- CSVの1行がAzure Storage Tableの1Entityという構造
- CSVのKey項目が存在しなければInsert(登録)、Key項目が存在すればUpdate(更新)する
- CSVのKey項目でStorageから検索して、登録または更新を判定
- Azure Storage TableのEntityのプロパティはすべて、String(文字列)の型を指定して、CSVの記載のまま登録したい
ハマったポイント1
Azure Storage Tableから取得した値が想定外!!?
$entity->addProperty("hoge", EdmType::STRING, csvRec[0]);
- プロパティから取得するときは、getValue関数を使用していた
$entity->getProperty("hoge")->getValue();
- 設定した値のまま取得できることを想定していた。
基本的には想定通りの動作だったが、小数点付きの数値などの場合に設定値と異なることがあった
- 設定値が "0001.0" の場合。getValueすると、 "1" で返されることを確認
- azure-storage-tableのライブラリの中を確認
- MicrosoftAzure\Storage\Table\Internal の JsonODataReaderWriter クラスでStorageから取得したEntityを変換している
- 上記クラスのparseOneEntity(private関数)でEntityを生成してプロパティを1つずつ設定している
- プロパティの型がStringの場合に、strvalした値をvalueに設定している
- strval(0001.0)の戻り値は、1となるため、今回の現象になっている
- Entityから以下のようにすると、想定通り、設定値と同様(0001.0)の値が取得できる
$entity->getProperty("hoge")->getRawValue();
ハマったポイント2
Entityを更新すると想定してプロパティの型が想定外!!?
- entityを更新するときには、Storageから取得したentityを元に一部のプロパティを変更していた
$tableClient = TableRestProxy::createTableService($connectionString);
$entity = $tableClient->getEntity("mytable", "tasksSeattle", 1);
$entity->setPropertyValue("hoge", "fuga");
$tableClient->updateEntity("mytable", $entity);
- 上記コード例のような場合、変更したプロパティは想定通りだったが、変更していないプロパティが元の型と別の型に自動的に変わっていることを確認
- 上記コード例でentityに「weight」というプロパティに「60.5」という値が設定されていた場合、updateEntityされると元々はString型だったものがDouble型に自動で変換されている。また日付型データも同様の現象が発生することを確認
- 取り急ぎの解決策として、Storageから取得したentityはそのまま使わないようにして、別途Entityを生成してaddPropertyすることで、すべてのプロパティをString型で保持するようにした
ハマったポイント3
getRawValueの値が想定外!!?
- ハマったポイント1で書いたとおり、getRawValue関数を使うことで設定したときの値がそのまま返されることを確認していた
- プロパティの型がString以外のときは、空文字が返されることを確認
- これについてはライブラリの仕様だと思う。ライブラリのソースコードの中にも「//Store the raw value of the string representation.」というコメントが記載されており、あくまでも文字列型のときにのみ使用されるものという認識。