Google fusion tables api v1.0 tips rev2

Preview:

DESCRIPTION

http://www.slideshare.net/awwa500/google-fusion-tables-api-v10-tipsにFTのTipsを書いてみたが、その後、気付いた点がいくつかあったので追加、修正してRev2を作ってみました。

Citation preview

Google Fusion Tables API v1.0 Tips Rev2

2013/5/3@awwa500Wataru Sato

1

自己紹介• Wataru Sato– 本業は通信キャリア研究所向けにソフトウェア

作っています– 個人的には Android 、 AWS(SDB) 、 Fusion Tables

などで遊んでいます• SmartTraining• ググれカス plug-in for twicca• 他

• @awwa500• awwa@gmail.com

2

きっかけ• Fusion Tables API が新しくなり、乗り換え

てみました• 乗り換えてみたはいいけど、ハマりまくっ

てドブ板踏み抜き過ぎて疲れました• 踏み抜いたドブ板の数を数えてみたら結

構あったので、まとめてみました• Rev2 :その後、気付いた点があったので

追記修正しました。

3

Google Fusion Tables とは• Google Drive で使える DB っぽいヤツ• ユーザプライベートなデータを(たぶ

ん)無料で利用できる

4

← コレ

Google Fusion Tables とは• データを手軽に可視化できる

5

Google Fusion Tables API とは• FT のデータにアクセスするための API• 2 つの API– SQL API• 既にオワコン• We will now shut down SQL API after January 14,

2013.

– API v1.0• 今ならこれを使うしかない• RESTful HTTP 経由で SQL 的なクエリ操作ができる• 結果は JSON or CSV で受け取る

6

ライブラリ• 実際、使おうと思ったら、依存関係にあるライブラ

リが 13 個。合計 3MB ありました。– https://

code.google.com/p/google-api-java-client/wiki/APIs#Fusion_Tables_API

• 個人的にはサイズがデカすぎな印象(元のアプリが5MB なもんで)

• あと、使い方覚えなきゃいけない的な面倒な臭いがプンプンするので使ってません

• もしかしたら、コレを使っていればドブ板踏み破る数は減っていたかも

• 是非使ってみて下さい7

基本• Google APIs console でサービス有効化• OAuth 2.0• HTTP リクエスト• レスポンスパース

• 詳しくは– https://

developers.google.com/fusiontables/docs/v1/using

8

OAuth2.0

• 通常は、普通に OAuth2 すればいい• Android の場合、 AccountManager 経由がセキュリティ

的に好ましい– 琴線探査: Android の AccountManager 経由で Google の

OAuth2 認証を行うには?(外部ライブラリ完全非依存版)• http://kinsentansa.blogspot.jp/2012/08/androidaccountmanagergoogle

oauth2.html

• Android で WebView 経由で行うのは好ましくない– Shogo’s Blog : OAuth の認証に WebView を使うのはやめよう

• http://shogo82148.github.com/blog/2012/11/24/no-more-webview/• この記事は Twitter の Oauth に関して書かれているが、 WebView の

脆弱性に関しては同じ事9

OAuth2.0

• ただし、今のところ Android のAccountManager 経由で OAuth2.0 可能なのは ICS 以降– https://developers.google.com/console/help/?hl=

ja• それ以前のバージョンでは、実質的に

WebView 経由もしくはそれと同等のセキュリティレベルでの方法でしかOAuth2.0 することができない。

10

テーブルアクセスの基本• Create table 時に返される tableId を使って

テーブル指定する必要がある

11

Create tableClient FT

tableId

SELECT * FROM <table_id>

レコードアクセスの基本• Insert row 時に生成される ROWID を使って

更新( update,delete )する必要がある

12

Insert rowClient FT

ROWID

UPDATE <table_id> SET <column_name> = <value> WHERE ROWID = <row_id>

レコード CRUDCRUD 手法 詳細Create Insert row 1 クエリ 1 レコード挿入

クエリを” ;” で繋げて 1 リクエストに複数クエリ送信可戻り値で ROWID を得ることができる

Import rows POST の Body に CSV を突っ込んで大量レコード挿入可戻り値で ROWID を得ることができない

Select Select rows 作成した Column の他、 ROWID を取得することができる

Update Update row ROWID 指定するか、無指定で全レコード対象任意の条件を指定することはできない

Delete Delete row ROWID 指定するか、無指定で全レコード対象任意の条件を指定することはできない 13

大量レコード挿入戦略~ Insert row ~

• Insert row では、 1 リクエストあたり 500 Insert までいける、とドキュメントに書いてある– https://developers.google.com/fusiontables/docs/v1/using#insertRo

w• しかし、 sql パラメータは QueryString• 実際には URL 長の制限を受ける

• と思っていたが、実は ContentType=application/x-www-form-urlencoded と指定してやると Body の sql= パラメータが有効になる。– そんなことドキュメントに書いてない。– ヾ (* ` Д´*) ノ“– 連続的に 17.8 万レコードまで Insert row 可能なことを確認

• それ以上実行すると 502 エラーが返る• 1 時間くらいすると復旧する

14

大量レコード挿入戦略~ Import rows ~

• Import rows なら 1 リクエストで 100MB までのデータを挿入できる

• しかし、戻り値で ROWID は取得できない• ROWID が欲しければ、 Import rows 後、 Select する

必要がある• しかし、 500 レコード以上を Import rows した場合、

すぐに Select しても ROWID が取得できない場合がある

• どうやら Import rows 後のレコード反映は、 500 レコードずつ分割されて非同期で実行されている模様

15

大量レコード挿入戦略~ Import rows ~

• 大量レコード Import 時の雰囲気

16

Import rows (over 500 rows)Client FT

Insert rows(500)

BackEnd

Insert rows(500)Select

Insert rows(500)

Insert rows(500)

Insert rows(500)

一部レコードしか取れない! 反映に時間がかかる

NumRowsReceived=2500

大量レコード挿入戦略~ Import rows ~

• 期待したレコード数になるまでポーリング

17

Import rows (over 500 rows)Client FT

Insert rows(500)

BackEnd

Insert rows(500)Select count()

Insert rows(500)

Insert rows(500)

Insert rows(500)

1000反映に時間

がかかるSelect count()

2000Select count()

2500Select

ROWID

NumRowsReceived=2500

大量レコード挿入戦略~ Import rows ~

• もしくは Import rows 後すぐには ROWID は取りに行かない。必要になったタイミングで個別に ROWID を Select 後、更新操作を行う

18

大量レコード挿入戦略~ Import rows ~

• しかも、 Import rows で大量レコード投入後、即同じテーブルに対して Import rowsすると– 417:Cannot execute ImportRows because another

task of type ImportRows is still running. でエラー– せつない

19

大量レコード挿入戦略~ Import rows ~

• Import rows の多重度上限は「 1」

20

Import rows (over 500 rows)Client FT

Insert rows(500)

BackEnd

Insert rows(500)

Insert rows(500)

Insert rows(500)

Insert rows(500)

反映に時間がかかる

他のタスク実行中なので NG!

Import rows (over 500 rows)

• まとめ– アクセス頻度に応じた作戦をとること

大量レコード挿入戦略~ Import rows ~

21

レコードアクセス頻度

方法

高い Insert row で戻ってきた ROWID を取得してローカルに記憶しておき、即更新処理を可能にしておく

低い Import rows 後、 ROWID は必要になったタイミングで個別に Select 後、目的の更新処理を実行するただし、焦って取りに行かない

• ROWID 指定した場合– レスポンスの affectedRows には影響を受けた

レコード数が整数で返ってくる• ROWID 指定しない場合– レスポンスの affectedRows に” all rows” という文字列が返ってくる

レコード更新( Update, Delete )時注意

22

_人人人人人人人人_>文字列が返ってくる< ̄ ^Y^Y^Y^Y^Y^Y^Y^Y ̄

• Insert row した場合の ROWID–割り当てられる ROWID は昇順とは限らない

• Order by 無指定時のソート順– ROWID の昇順でソートされて返ってくる

• Order by に ROWID を指定すると 503– 指定してはいけない

• ROWID = 0 で Select すると 503– 指定してはいけない

ROWID に関する注意

23

• そんな機能はない• あるわけがない• どうしてもやりたければ– A案)子テーブルに親テーブルレコードの ROWID

を格納する Column を設ける– B案)親テーブルのレコード毎に子テーブルを分

けて、親テーブルに子テーブルの tableId を格納する Column を設ける

• 無論、関連情報は自分で更新する、制約がはれるわけではない

テーブル間の外部参照

24

• A案)子テーブルに親テーブルレコードのROWID を格納する Column を設ける

テーブル間の外部参照

25

ROWID

1

2

ROWID PARENT_ROWID

1 1

2 1

3 2

4 2

親テーブル 子テーブル

• B案)親テーブルのレコード毎に子テーブルを分けて、親テーブルに子テーブルのtableId を格納する Column を設ける

テーブル間の外部参照

26

ROWID CHILD_TABLE_ID

1 XXX

2 YYY ROWID

1

2

親テーブル

子テーブル( tableId=XXX )

ROWID

1

2

子テーブル( tableId=YYY )

大量なテーブル生成は大量な Import を必要とする503発生の原因になりやすいので注意する

タイムアウト• クライアントタイムアウト値は最低でも

60秒くらいは必要– HttpClient などを利用しているとタイムアウト

値が短かったりするので長めに設定すること

27

HTTP 503 との闘い• HTTP 503 : Service Unavailable–裏でナニかが起きた–ナニ• 高頻度のアクセスによるブロック• Select row で ROWID で order by• Select row で ROWID = 0• Fusion Tables 自体の不具合(たぶん)• など

28

アクセス制限• Google APIs console

• 制限はこれだけではない– 上限に関して明確には規定されていない

• 問合せても回答がもらえない– 特に Import rows で発生しやすい

• 例) Import rows をスリープなしで 18回繰り返すと発生– 復旧

• まる 1日制限されたり、数分で復旧したり、とにかくよくわからない– 影響範囲

• ユーザ単位

29

誰かに質問したい時は• 技術的な質問は Stackoverflow を使うこと• Google Group の Fusion Tables API グループ

は技術以外に関するディスカッションの場という位置づけ–誤って質問を投げてしまうと、ディスカッションの途中で「 Stackoverflow に行け!」と言われて議論はウヤムヤになる

30

Stackoverflowへ質問する時• 503 が発生した時の質問方法• 以下の 2 点を質問内容に含めておくと回答

が得られやすい– どういうリクエストを投げたのか?–具体的なレスポンスの Body(JSON)

• Try it! を使うとわりと便利– https://developers.google.com/fusiontables/docs/v

1/reference/query/sqlGet#try-it• 「 503起きた-!」だけでは何も伝わらな

い31

Try it!

32