2016-05-20 6 views
0

次のコードでdjangoを実行しているサーバーから融合テーブルを作成しようとしていますが、サーバーエラー500が発生して失敗します。Pythonのサービスアカウントを使用した融合テーブルの作成

scope = ['https://www.googleapis.com/auth/fusiontables'] 
credentials = ServiceAccountCredentials.from_json_keyfile_name(EE_CREDENTIALS, scope) 
http_auth = credentials.authorize(Http()) 

def create_table(name, description, columns, data=None): 
    ft_service = build('fusiontables', 'v2', http_auth) 
    body = dict(name=name, description=description, columns=columns) 
    table = ft_service.table() 
    result = table.insert(body=body).execute(num_retries=3) # failing here 
    if data is not None: 
     if not os.path.exists(TEMP_DIRPATH): 
      os.makedirs(TEMP_DIRPATH) 
     keys = data[0].keys() 
     if len(columns) != len(keys): 
      raise ValueError("mismatch in number of columns") 
     filename = TEMP_DIRPATH + str(result.tableId) + ".csv" 
     with open(filename, 'wb') as upload_file: 
      dict_writer = csv.DictWriter(upload_file, keys) 
      dict_writer.writeheader() 
      dict_writer.writerows(data) 
     ft_service.importRows(tableId=result.tableId, media_body=filename, startLine=1, isStrict=True, 
           encoding="auto-detect", delimiter=",").execute(num_retries=3) 
    return result.tableId 


def test_create_table(filename): 
    data = [] 
    columns = [] 
    with open(filename, 'rb') as csvfile: 
     reader = csv.reader(csvfile) 
     for row_index, row in enumerate(reader): 
      if row_index == 0: 
       header = list(row) 
       for col_index, col in enumerate(row): 
        if col_index == 24 or col_index == 25: 
         columns.append({"name": header[col_index], "type": "LOCATION"}) 
        else: 
         columns.append({"name": header[col_index], "type": "STRING"}) 
      else: 
       # 24 and 25 are latitude and longitude. 
       if caught(float, row[24]) or caught(float, row[25]): 
        continue 
       properties = {} 
       for col_index, col in enumerate(row): 
        # 21 is ch4 
        if col_index == 21: 
         properties[header[col_index]] = 0 if caught(float, col) else float(col) 
        else: 
         properties[header[col_index]] = col 
       data.append(properties) 
    table_id = create_table('chino-20150110', 'locality = chino and date = 20150110', columns, None) 
    print "created fusion table id is " + str(table_id) 


test_create_table('C:/Users/JohnsonCharles/Desktop/chino-20150110.csv') 

そして、私が取得エラーはこれです:私もそれを使用するGoogleドライブを知っているんどのように思ったんだけど

googleapiclient.errors.HttpError: <HttpError 500 when requesting https://www.googleapis.com/fusiontables/v2/tables?alt=json returned "Backend Error"> 

。私はバックエンドからフュージョンテーブルを作成しているので、フュージョンテーブルの作成に特定のGoogleドライブを使用するにはどうすればいいですか?

答えて

1

This postが問題の解決に役立ちました。 isExportable属性は、サービスアカウントを使用してフュージョンテーブルを作成するときに、明示的にtrueに設定する必要があります。この記事では、どのドライブを使うのかという私の懸念も説明しました。デフォルトでは、フュージョンテーブルを作成したユーザーのドライブになります。この場合、サービスアカウントです。それは他のユーザーに許可を与える方法を明確に説明しましたが、投稿はJavaにあります。私はPythonで同じものを実装しようとしました。ここには、同じ問題に直面している人のために私の更新されたコードがあります。

from googleapiclient.discovery import build 
from httplib2 import Http 
from oauth2client.client import GoogleCredentials 
from googleapiclient.http import MediaFileUpload 

scopes = ['https://www.googleapis.com/auth/fusiontables', 'https://www.googleapis.com/auth/drive'] 
credentials = GoogleCredentials.from_stream(EE_CREDENTIALS).create_scoped(scopes=scopes) 
http_auth = credentials.authorize(Http()) 


def create_table(name, description, columns, data=None): 
    ft_service = build(serviceName='fusiontables', version='v2', http=http_auth, credentials=credentials) 
    drive_service = build(serviceName='drive', version='v3', http=http_auth, credentials=credentials) 
    body = dict(name=name, description=description, columns=columns, isExportable=True) 
    table = ft_service.table() 
    result = table.insert(body=body).execute() 
    permissions = drive_service.permissions() 
    permissions.create(fileId=result["tableId"], 
         body={"emailAddress": "<your email id>@gmail.com", "type": "user", "role": "writer"}, 
         sendNotificationEmail=False).execute() 
    if data is not None: 
     if not os.path.exists(TEMP_DIRPATH): 
      os.makedirs(TEMP_DIRPATH) 
     keys = [column["name"] for column in columns] 
     filename = TEMP_DIRPATH + str(result["tableId"]) + ".csv" 
     with open(filename, 'wb') as upload_file: 
      dict_writer = csv.DictWriter(upload_file, keys) 
      dict_writer.writeheader() 
      dict_writer.writerows(data) 
     media_body = MediaFileUpload(filename=filename, mimetype="application/octet-stream") 
     table.importRows(tableId=result["tableId"], media_body=media_body, startLine=1, 
         isStrict=True, encoding="UTF-8", delimiter=",").execute() 
    return result["tableId"] 

ドライブサービスの引数の詳細については、thisを参照してください。ここで使用したドライブAPIはv3であり、作成したフュージョンテーブルの表示を変更する場合はをFalseに、typedomainまたはanyoneに設定する必要があります。デフォルトでは、プライベートだが共有しているユーザーはアクセスできる。

+0

ところで、私はフュージョンテーブルがGoogleドライブで占有するスペースに関心があり、特定のドライブでそれを作成することについて私の質問の背後にある理由でした。しかし、私のGoogleドライブのフュージョンテーブルの詳細から、彼らはこの執筆時点で無料です。 –

関連する問題