経緯
datastoreからexporterでRDBにデータ移行。
その際にdatastoreの該当のkindから移行先のDBのテーブルに同じレコード数が移行できているか確認したい。
問題
GAE datastoreを参照するdatastoreViewではselect count(*) ...が出来ない
対応方法
datastoreViewで表示されるデータをスクレイピングしてカウント
面倒だったこと
- 現状のdatastoreViewはデータを非同期で読み込んでいるのでスクレイピングが困難
- 古いdatastoreViewでパラーメータにlimitとoffsetを渡しながらページ遷移してカウントしていった。
しかもlimitは200が上限...
旧datastoreView
スクレイピングのサンプル
googleのログインはEメール入力してから遷移してパスワード入力の2段階になる。
Mechanizeで対応するにもちょっと面倒
sample.rb
agent = Mechanize.new
# ログインしていない時に旧DataStoreのURLにアクセスしてリダイレクトされた先にURL
agent.get 'https://accounts.google.com/ServiceLogin?service=ah&passive=true&continue=XXXXXXXXXXX'
form = agent.page.forms.find {|f| f.form_node['id'] == "gaia_loginform"}
form.field_with(:id => "Email").value = 'googleのアカウント'
form.click_button
form = agent.page.forms.find {|f| f.form_node['id'] == "gaia_loginform"}
form.field_with(:name => "Passwd").value = 'googleのパスワード'
form.click_button
limit_count = 200
offset_count = 0
begin
# 取得したいDataStoreのkindやnamespaceを指定したURL
page = agent.get("https://appengine.google.com/datastore/explorer?<ほげほげ>+where+type+%3D+%2710%27&limit=#{limit_count}&offset=#{offset_count}").content.toutf8
doc = Nokogiri::HTML.parse(page)
result = doc.xpath("//table/tbody/tr").count
offset_count += limit_count
puts "result:#{result}"
end while result == limit_count
amount = limit_count * (page_count - 1) + result
puts "amount:#{amount}
end