【问题标题】:fusion table creation using service account in python在 python 中使用服务帐户创建融合表
【发布时间】:2016-05-21 17:48:57
【问题描述】:

我正在尝试使用以下代码从运行 django 的服务器创建一个融合表,但它一直失败并出现 500 服务器错误。

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')

我得到的错误是这样的:

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

我也想知道它是如何知道使用哪个 google 驱动器的。由于我是从后端创建融合表,如何让我的应用程序使用特定的谷歌驱动器来创建融合表?

【问题讨论】:

    标签: python google-fusion-tables


    【解决方案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,如果你想改变创建的融合表的可见性,你必须将allowFileDiscovery设置为False,将type设置为domainanyone .默认情况下,它是私有的,但您与之共享的用户可以访问。

    【讨论】:

    • 顺便说一句,我担心融合表会在谷歌驱动器上占据的空间,这也是我在特定驱动器中创建它的问题背后的原因。但是从我的谷歌驱动器中的融合表的详细信息来看,它们在撰写本文时是免费的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-06-27
    • 2021-09-30
    • 1970-01-01
    • 1970-01-01
    • 2022-11-08
    • 2021-09-27
    • 1970-01-01
    相关资源
    最近更新 更多