2016-05-20 9 views
0

Ich versuche, eine Fusion-Tabelle von meinem Server mit django mit dem folgenden Code erstellen, aber es bleibt mit einem Fehler 500 Server fehlgeschlagen.Fusion Tabelle Erstellung mit Service-Konto in 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') 

Und die Fehler, die ich bekommen, ist dies:

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

ich auch mich frage, wie funktioniert es wissen, welche Google-Laufwerk zu verwenden. Da ich die Fusion Tabellen aus dem Backend erstellen, wie kann ich meine Anwendung ein bestimmtes Google-Laufwerk für die Erstellung von Fusionstabellen verwenden?

Antwort

1

This post geholfen, das Problem zu lösen. isExportable Attribut muss explizit auf true festgelegt werden, wenn versucht wird, eine Fusionstabelle mithilfe des Dienstkontos zu erstellen. Der Post erklärte auch meine Bedenken, welches Laufwerk verwendet werden würde. Standardmäßig ist dies das Laufwerk des Benutzers, der die Fusionstabelle erstellt hat. In diesem Fall handelt es sich um das Dienstkonto. Es wurde klar erklärt, wie man anderen Benutzern die Erlaubnis gibt, aber der Beitrag ist in Java. Ich habe versucht, das gleiche in Python zu implementieren und hier ist mein aktualisierter Code für alle, die das gleiche Problem konfrontiert.

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"] 

Siehe this Link für Antrieb Service Argument Details. Beachten Sie, dass die hier verwendete Laufwerk-API v3 ist. Wenn Sie die Sichtbarkeit der erstellten Fusionstabelle ändern möchten, müssen Sie allowFileDiscovery auf False und type auf domain oder anyone einstellen. Standardmäßig ist es privat, aber für die Benutzer zugänglich, mit denen Sie geteilt haben.

+0

Übrigens war ich besorgt über den Platz, den die Fusion-Tabellen auf dem Google-Laufwerk belegen würden und war der Grund für meine Frage, wie ich es in einem bestimmten Laufwerk erstellen könnte. Aber von den Details der Fusionstabelle in meinem Google Drive sind sie zum Zeitpunkt des Schreibens frei. –