スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。
コメント (-)
承認待ちコメント
このコメントは管理者の承認待ちです
2013/01/16 19:58
コメントの投稿
トラックバック (-)
-
管理人の承認後に表示されます
2012/10/23 11:53

Google SpreadSheets API のメモ (pythonのサンプル付き)

前から興味のあったGoogle Docs API。
ようやくSpreadSheetを使う理由ができたので最近調べています。
あまり日本語情報がないようなので、少しメモを書いてみます。
(APIの公式ページ)
http://code.google.com/intl/ja/apis/spreadsheets/

最新のSpreadSheets API v3.0でデータを操作するには、
「list-based」「table-based」「cell-based」の3つがある。

「list-based」は行単位にデータを扱う最もベーシックなもの。
「table-based」は「list-based」に似てるけど、データベースっぽく扱うもの。
いろんな言語で実装されているDataSet的な仕組みをイメージしてもらえばたぶんOK。
「cell-based」はセル単位で扱うもの。
「cell-based」はバッチ更新機能があり一番柔軟に使えるかと思ったんだが、現時点でセルの追加ができない模様。
(調べてないけど削除もかも)
全項目が常に埋まるデータならいいが、そうでもないので今回はパス。
「list-based」「table-based」なら「table-based」のほうが「more flexible」ということなので、
今回はこれを使うことにした。

あまりごちゃごちゃ書いてもわかりづらいと思うので、詳しくは記事の最後のサンプルソース(python)をどうぞ。

APIの公式ページにpythonはv1.0にしか書いてませんが、実際には全部実装されているようです。

(pythonライブラリのページ)
http://code.google.com/p/gdata-python-client/

ただライブラリのページにもサンプルなどあんまりありません。
pydocやソースを参考に適当にやる感じになります。

注意点としては、

・列名は小文字にしないと更新できない。例えば「itemId」という列は「itemid」としないとだめ
・値は全部文字列にしないとだめ
・データベース名は前方一致でマッチしちゃう模様。
 例えば「test_xxx」というシートがあって、「test」というデータベース名で取得すると「test_xxx」をもってきちゃう
・"True"は"TRUE"になる模様
・書式が自動適用される。例えば"12345"は数値として設定される。
 これはいいんだけど"2-10"が"2010/2/10"の日付になっちまったので注意。
 指定できそうだけど未調査

あと解説ページに、

You can't create a table using the Spreadsheets GUI; you can create a table only by using the Data API.

と書いてあり、これは
GoogleドキュメントのWebページからはテーブルは作れません、
つまり普通に作ったシートではダメです、
という意味だと思ったのですが、普通に作ったシートも同じように扱える模様。
Webページからの更新ができなきゃ使えねーと思いましたがそんなことなさそうです。

以下、サンプルです。



# -*- coding: utf-8 -*-

import logging
import gdata.spreadsheet.text_db

#-------------------------------------------------------------------------------
user = 'xxx@xxx'
passwd = 'xxxx'

#-------------------------------------------------------------------------------
def normValue(val):

if isinstance(val, basestring) or val is None:
return val
elif isinstance(val, bool):
return str(val).upper()
else:
return str(val)

#-------------------------------------------------------------------------------
def getDB(dbClient, name):

dbs = dbClient.GetDatabases(name = name)
if len(dbs) > 0:
return dbs[0]
else:
logging.info('Create new database (%s)', name)
return dbClient.CreateDatabase(name)

#-------------------------------------------------------------------------------
def getTable(db, name, fields):

tables = db.GetTables(name = name)
if len(tables) > 0:
table = tables[0]
table.LookupFields()
return table
else:
logging.info('Create new table (%s.%s)', db.entry.title.text, name)
return db.CreateTable(name, fields)

#-------------------------------------------------------------------------------
def loadRecordMap(table, indexField = 'id'):

map = {}
for record in table.GetRecords(1, 999999999):
map[record.content[indexField]] = record
return map

#-------------------------------------------------------------------------------
def saveData(table, curDataMap, newDataList, indexField = 'id'):

queryBase = indexField + ' = "%s"'
indexes = []
for data in newDataList:
indexValue = data[indexField]
indexes.append(indexValue)
curRec = curDataMap.get(indexValue)
if curRec is None:
values = {}
for field in table.fields:
val = data.get(field)
if val is not None:
values[field.lower()] = normValue(val)
logging.info('Add new record (%s.%s)', table.name, indexValue)
table.AddRecord(values)
else:
modified = False
for field in table.fields:
newVal = normValue(data.get(field))
curVal = curRec.content.get(field)
if newVal != curVal:
curRec.content[field] = newVal
modified = True
logging.info('%s.%s changed (%s -> %s)' % (indexValue, field, curVal, newVal))
if modified:
logging.info('Update record (%s.%s)', table.name, indexValue)
curRec.Push()

for (id, rec) in curDataMap.iteritems():
if id not in indexes:
logging.info('Delete record (%s.%s)', table.name, id)
rec.Delete()

#-------------------------------------------------------------------------------
def main():

testFields = (
'id', 'name', 'price',
)
newData = (
dict(id = 'cat', name = u'猫', price = 50000),
dict(id = 'dog', name = u'犬', price = 30000),
dict(id = 'monkey', name = u'猿', price = 100000),
dict(id = 'hippopotamus', name = u'カバ', price = 500000),
)

dbClient = gdata.spreadsheet.text_db.DatabaseClient(user, passwd)

logging.debug('Loading current data')
testTable = getTable(getDB(dbClient, 'testDB'), 'test', testFields)
curData = loadRecordMap(testTable)
logging.debug('Save new data')
saveData(testTable, curData, newData)

#-------------------------------------------------------------------------------
if __name__ == '__main__':

logging.getLogger().setLevel(logging.DEBUG)

main()

コメント (1)
承認待ちコメント
このコメントは管理者の承認待ちです
2013/01/16 19:58
コメントの投稿
トラックバック (1)
-
管理人の承認後に表示されます
2012/10/23 11:53
次のページ(mongodbが動かなくなった (mongodb-stable 20101209 解決済))
プロフィール

MAO

間男(MAO)

最新記事
カテゴリ
戯言 (38)
テンプレート (2)
検索フォーム
ブロとも申請フォーム

この人とブロともになる

リンク
このブログをリンクに追加する
RSSリンクの表示
google adsence
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。