Google Fusion Tables - 如何在媒体下载中获得ROWID

时间:2018-02-01 01:17:08

标签: google-fusion-tables

我正在使用这样的请求查询融合表:

https://www.googleapis.com/fusiontables/v2/query?alt=media&sql=SELECT ROWID,State,County,Name,Location,Geometry,[... many more ...] FROM <table ID>

此查询的结果超过10MB,因此我必须包含alt=media选项(对于较小的查询,我可以删除此选项,但问题不存在)。响应是在csv中,正如文档所承诺的那样。响应的第一行似乎是与我的查询字符串完全匹配的标题行(除了它显示rowid而不是ROWID):

rowid,State,County,Name,Location,Geometry,[... many more ...]

但是以下行不包含行ID。每行以查询中请求的第二个项开头 - 似乎忽略了行ID:

WV,Calhoun County,"Calhoun County, WV, USA",38.858 -81.1196,"<Polygon><outerBoundaryIs>...

这有什么办法吗?当表很大时,如何从表中检索行ID?

1 个答案:

答案 0 :(得分:0)

通过Google's Python API Client library发出的“媒体”请求也会出现缺少ROWID,例如

def doGetQuery(query):
    request = FusionTables.query().sqlGet_media(sql = query);
    response = request.execute();
    ft = {'kind': "fusiontables#sqlresponse"};
    s = queryResult.decode();    # bytestring to string
    data = [];
    for i in s.splitlines():
        data.append(i.split(','));
    ft['columns'] = data.pop(0); # ['Rowid', 'A', 'B', 'C'] 
    ft['rows'] = data;           # [['a1', 'b1', 'c1'], ...]
    return ft;

你可能至少比我少一个问题 - 这个sqlGet_media方法只能用“纯”GET请求 - 一个足够长的查询(2-8k字符)来发送,因为被覆盖的POST生成502 Bad Gateway错误,即使是微小的响应大小,例如SELECT COUNT()的结果。与非媒体请求相同的查询可以完美地工作(当然,响应大小不超过10 MB)。

您和我的问题的解决方案是使用OFFSETLIMIT批处理请求,以便不会命中10 MB响应限制。估计调用站点的平均响应行的大小,将其传递给包装函数,让包装器处理向输入SQL添加OFFSET和LIMIT,然后将多查询结果整理为所需格式的单个输出:

def doGetQuery(query, rowSize = 1.):
    limitValue = floor(9.5 * 1024 / rowSize) # rowSize in kB
    offsetValue = 0;
    ft = {'kind': "fusiontables#sqlresponse"};
    data = [];
    done = False;
    while not done:
        tail = ' '.join(['OFFSET', str(offsetValue), 'LIMIT', str(limitValue)]);
        request = FusionTables.query().sqlGet(sql = query + ' ' + tail);
        response = request.execute();
        offsetValue += limitValue;
        if 'rows' in response.keys():
            data.extend(response['rows']);
        # Check the exit condition.
        if 'rows' not in response.keys() or len(response['rows']) < limitValue:
            done = True;
        if 'columns' not in ft.keys() and 'columns' in response.keys():
            ft['columns'] = response['columns'];

    ft['rows'] = data;
    return ft;

可以扩展此包装以处理偏移和限制的实际所需用途。理想情况下,对于FusionTable或其他REST API方法,它们为本机分页提供了list()和list_next()方法,但FusionTable :: Query没有这样的功能。鉴于FusionTable API /功能更新的速度非常慢,我不希望ROWID神奇地出现在alt=media下载中,或者GET-turned-POST媒体格式查询可以正常工作,所以编写自己的包装器是为你节省很多头痛。