TabPy: Python, возвращающий Json в Tableau, «Номер синтаксического анализа ошибки» - PullRequest
2 голосов
/ 06 марта 2019

Я пытаюсь использовать вычисляемое в Таблице поле для использования моего скрипта Python, который получает данные JSON. Моя конечная цель - поместить эти данные в таблицу в табличном формате.

Я прочитал, что JSON легче попасть в таблицу, чем объект dataframe.

В настоящее время я использую его в программе Spyder. и выполните это, чтобы получить мои данные.

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

В моем вычисляемом поле я получаю сообщение об ошибке: «Error Parsing Number» на

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

1 голос
/ 08 марта 2019

Добавление этого ответа для потомков и для упрощения моего предыдущего ответа и результирующей темы.

Представленный в вопросе скрипт Python предназначен для загрузки данных непосредственно в таблицу. TabPy предназначен для работы с данными, уже существующими в Таблице, в отличие от источника при приеме внутрь.

Здесь необходимо разместить выходные данные скрипта Python в промежуточном месте, где он может быть подключен с помощью Tableau.

1 голос
/ 07 марта 2019

Посмотрите руководство Tableau к Создание вычислений Python в Tableau .

В общем, формат должен быть таким:

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

Из того, что я вижу, вам нужно добавить кавычки в вычисляемое поле, заменить любые переменные поля, которые необходимо передать, на _argX, добавить запятые в вычисляемое поле, а затем список полей, которые нужно передать как арг.

Обратите внимание, что каждый раз, когда вы видите ошибку "Расчет содержит ошибки" в окне поля Таблицы вычислений, проблема заключается в поле Таблицы вычислений (Форматирование / компиляция) и не обязательно с базовым Python. (Ошибка, которую вы видите, - красная сельдь. Интерпретатор Tableau Calculated Field видит «.» Как десятичное число и ожидает получить за ним число.) В окне рассчитанного поля Tableau не сможет проверить лежащий в основе Python - он только передает его в TabPy в виде строки. Также верно и обратное: просмотр «Этот расчет действителен» в окне «Вычисляемое поле таблицы» не обязательно означает, что скрипт Python вернется правильно.

Надеюсь, это поможет.

Изменить в ответ на комментарий:

Ниже приведен пример использования кода, который вы указали в своем вопросе.

  • Заменены двойные кавычки в скрипте Python на одинарные. Таким образом, Tableau сможет отличать свои двойные цитаты. (Таблица аналогична Python в том, что она одинаково обрабатывает двойные и одинарные кавычки.)
  • Заменены входные параметры для getData () с _arg1 по _arg4.
  • Передаются [Дата начала], [Дата окончания], [Имя узла] и [Тип] как аргументы после передачи скрипта Python в виде строки. (Они внедряются в строку как _arg1 - _arg4. (ATTR () может быть не правильным методом агрегирования - вам придется экспериментировать.)
  • Поле Calculated теперь, по крайней мере, будет компилироваться, однако я не могу гарантировать, что оно будет выполнено на стороне Python или что оно выполнит то, что вы пытаетесь сделать.
  • Я не уверен, как get1D () будет реагировать здесь. Вам, возможно, придется указать ваши _arg1 - _arg4 в качестве параметров. Необходимо проделать определенную работу - и, возможно, даже переформатировать код, чтобы принять аргументы Tableau.

Пожалуйста, ознакомьтесь с документацией 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]
)  
...