TabPy:Python将Json返回Tableau,“错误解析编号”

时间:2019-03-06 18:00:05

标签: python tableau tabpy

我正在尝试使用Tableau计算字段来使用我的Python脚本,该脚本获取JSON数据。我的最终目标是将这些数据以表格格式导入表格。

我已经阅读了JSON,相对于dataframe对象,它更容易进入Tableau。

我目前在Spyder程序中使用它。并执行此操作以获取我的数据。

print (get1D ("2019-02-02", "2019-02-05", "Tableau", "Limits"))

在我的计算字段中,出现错误:“错误解析编号”打开

.format(status_code))

错误消息:

enter image description here

任何帮助将数据导入表格都将不胜感激。这是我的完整剧本。

SCRIPT_INT(  

import time  
import requests  
import json  
import pandas as pd  
import re  
import urllib3  
import math  

from io import StringIO  

from datetime import datetime, date,timedelta  
from pandas.tseries.offsets import BDay  
from urllib.parse import urlencode  
from flask import json  


def call_api(url, request_dict, post):     


    if post:  
        header = {'content-type':'application/json'}  

        resp = requests.post(url, data=json.dumps(request_dict), auth=('user', 'pass'), headers = header, verify=False)  
    else:  
        url = url + urlencode(request_dict)  


        resp = requests.get(url, auth=('user', 'pass'), verify=False)  




    status_code = resp.status_code  

    if status_code == 401:  
        raise ValueError("There is an error with the connection.\nLogin failed. \nNot authorized. Please check your credentials and try again.\nStatus code {}".format(status_code))  
    elif status_code == 404:  
        raise ValueError("There is an error with the connection.\nCould not connect to the server.\nStatus code {}".format(status_code))  
    elif status_code == 200:  
        pass  
    else:  
        raise ValueError("There is an error with the connection.\nStatus code {}".format(status_code))  

    return resp  


def getData (startDate, endDate, nodeName, Type, Id):  



    request_dict = [{  
        "hierarchy": "Tableau",  
        "nodeName": nodeName,  
        "FilterId": Type,  
        "Id": Id ,  
    }]  


    url = "https://sampleurl/startDate={0}&endDate={1}"   



    startDate = datetime.strptime(startDate, '%Y-%m-%d')  
    startDate = startDate.strftime ('%Y%m%d')  

    endDate = datetime.strptime(endDate, '%Y-%m-%d')  
    endDate = endDate.strftime ('%Y%m%d')  


    url = url.format(startDate, endDate)  


    resp = call_api(url, request_dict, True)   

    return resp.json ()  

def get1D(startDate, endDate, nodeName, Type):  
    return getData (startDate, endDate, nodeName, Type, 1)  
)  

2 个答案:

答案 0 :(得分:1)

看看Tableau的Authoring Python Calculations in Tableau指南。

通常,格式应为:

SCRIPT_INT("import xyz foo=_arg1+_arg2 return foo", SUM([A number]), SUM([Another Number])

据我所知,您需要在计算所得的字段中添加引号,用_argX替换所有需要传递的字段变量,在计算所得的字段中添加逗号,然后像这样传递要通过的字段列表args。

请注意,只要在Tableau Calculated字段窗口中看到错误“计算包含错误”,问题就出在Tableau Calculated字段内(格式化/编译),而不一定是底层Python。 (您看到的错误是红色鲱鱼。TableauCalculated Field解释器将“。”显示为十进制,并期望在其后面接收到一个数字。)在已计算字段窗口中,Tableau无法检查基础Python-仅将其作为字符串传递给TabPy。相反的情况也是如此-在Tableau Calculated Field窗口中看到“此计算有效”并不一定意味着Python脚本将正确返回。

希望这会有所帮助。

根据评论进行编辑:

下面是使用问题中提供的代码的示例。

  • 在Python脚本中用单引号替换了双引号。这样,Tableau将能够区分自己的双引号。 (Tableau与Python相同,因为它对待双引号和单引号相同。)
  • 用_arg1至_arg4代替了getData()的输入参数。
  • 在将Python脚本作为字符串传递后,将[开始日期],[结束日期],[节点名称]和[类型]作为参数传递了。 (这些被植入到字符串中,从_arg1到_arg4。(ATTR()在这里可能不是正确的聚合方法-您必须进行试验。)
  • 现在,Calculated字段至少会编译,但是,我不能保证它会在Python端执行或完成您要尝试的操作。
  • 我不确定get1D()在这里会如何反应。您可能也必须将_arg1到_arg4用作参数。需要完成一些工作-甚至可能是重新格式化代码以接受Tableau args。

请阅读TabPy文档,以获取有关其用法的更多说明,而不是我在此处提供的内容。另外,这是一篇不错的博客文章。如果使用得当,其功能非常强大。

祝你好运!

SCRIPT_INT(  

"import time  
import requests  
import json  
import pandas as pd  
import re  
import urllib3  
import math  

from io import StringIO  

from datetime import datetime, date,timedelta  
from pandas.tseries.offsets import BDay  
from urllib.parse import urlencode  
from flask import json  


def call_api(url, request_dict, post):     


    if post:  
        header = {'content-type':'application/json'}  

        resp = requests.post(url, data=json.dumps(request_dict), auth=('user', 'pass'), headers = header, verify=False)  
    else:  
        url = url + urlencode(request_dict)  


        resp = requests.get(url, auth=('user', 'pass'), verify=False)  




    status_code = resp.status_code  

    if status_code == 401:  
        raise ValueError('There is an error with the connection.\nLogin 
        failed. \nNot authorized. Please check your credentials and try 
    again.\nStatus code {}'.format(status_code))  
    elif status_code == 404:  
        raise ValueError('There is an error with the connection.\nCould not 
        connect to the server.\nStatus code {}'.format(status_code))  
    elif status_code == 200:  
        pass  
    else:  
        raise ValueError('There is an error with the connection.\nStatus 
    code {}'.format(status_code))  

    return resp  


def getData (startDate, endDate, nodeName, Type, Id):  



    request_dict = [{  
        'hierarchy': 'Tableau',  
        'nodeName': nodeName,  
        'FilterId': Type,  
        'Id': Id ,  
    }]  


    url = 'https://sampleurl/startDate={0}&endDate={1}'  



    startDate = datetime.strptime(startDate, '%Y-%m-%d')  
    startDate = startDate.strftime ('%Y%m%d')  

    endDate = datetime.strptime(endDate, '%Y-%m-%d')  
    endDate = endDate.strftime ('%Y%m%d')  


    url = url.format(startDate, endDate)  


    resp = call_api(url, request_dict, True)   

    return resp.json ()  

def get1D(startDate, endDate, nodeName, Type):  
    return getData (_arg1, _arg2, _arg3, _arg4, 1)"
,
ATTR([Start Date]),ATTR([End Date]),ATTR([Node Name], ATTR([Type]
)  

答案 1 :(得分:1)

添加此答案以供后代使用,并简化我以前的答案和所获得的线索。

问题中显示的Python脚本旨在将数据直接加载到Tableau中。 TabPy旨在对Tableau中已经存在的数据进行操作,而不是作为摄取的源。

这里有必要将Python脚本的输出放置在中间位置,然后Tableau可以将其连接到该位置。