You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

将Replit的Python脚本迁移到本地TabPy服务器时遇'DataFrame不可调用'错误

问题描述

我编写了一段Python脚本调用美国国家海洋和大气管理局(NOAA)接口,通过邮政编码获取气象站列表并转换为Pandas DataFrame。该脚本在Replit上运行正常,但迁移到本地TabPy服务器后,尽管日志显示DataFrame已正常构建,却在Tableau Prep中出现TypeError : 'DataFrame' object is not callable错误。脚本代码如下:

import requests;
import pandas as pd;
import json;

zip = '97034'
userToken = 'foobar123'
headerCreds = dict(token = userToken)
url = 'https://www.ncei.noaa.gov/cdo-web/api/v2/stations?&locationid=ZIP:' + zip
global dfWorking

def get_stations_for_zip():

    r = requests.get(url, headers = headerCreds)
    data = json.loads(r.text)
                     
    if 'results' in data:
        data = data.get('results')
        dfWorking = pd.DataFrame(data)
    
        # Column datatypes as received
        # elevation        float64
        # mindate           object
        # maxdate           object
        # latitude         float64
        # name               int64
        # datacoverage     float64
        # id                object
        # elevationUnit     object
        # longitude        float64

        dfWorking = dfWorking.astype({'name': 'str'})
      
        # dfWorking['name'] = dfWorking.index
        # defining an index converts back to float64
  
        print(dfWorking)
    else:
      print('no results object in response')
      
    return dfWorking

# Note: the below prep functions are undefined until they are on a TabPy server
  
def get_output_schema():
    return pd.DataFrame({
        'elevation' : prep_decimal(),
        'mindate' : prep_string(),
        'maxdate' : prep_decimal(),
        'latitude' : prep_date(),
        'name' : prep_string(),
        'datacoverage' : prep_decimal(),     
        'id' : prep_decimal(),
        'name' : prep_string(),
        'elevationUnit' : prep_decimal(),     
        'longitude' : prep_decimal()      
    });

get_stations_for_zip()

问题分析与解决方案

出现'DataFrame' object is not callable错误,核心原因是TabPy与Tableau Prep的交互逻辑不匹配,结合代码细节,主要问题和修复点如下:

1. 函数注册逻辑错误

脚本最后直接执行get_stations_for_zip(),会立即返回DataFrame对象,但TabPy需要的是注册可调用的函数服务,而非直接返回数据。Tableau Prep尝试调用这个返回的DataFrame,自然触发“对象不可调用”的错误。

2. get_output_schema存在多处错误

  • 重复定义name列,字典键重复会导致Schema解析异常
  • 数据类型映射完全错误:比如maxdate应为日期类型、id应为字符串类型,错误的类型映射会让Tableau Prep无法识别返回的DataFrame结构

3. 全局变量冗余且易混淆

定义全局dfWorking但函数内又重新赋值局部变量,容易引发变量作用域冲突,导致返回结果不符合预期


修正后的完整代码

import requests
import pandas as pd
import json
from tabpy.tabpy_tools.client import Client

# 配置参数
DEFAULT_ZIP = '97034'
USER_TOKEN = 'foobar123'
HEADERS = {'token': USER_TOKEN}

def get_stations_for_zip(zip_input=None):
    # 支持动态传入邮政编码,增强灵活性
    target_zip = zip_input if zip_input is not None else DEFAULT_ZIP
    api_url = f'https://www.ncei.noaa.gov/cdo-web/api/v2/stations?locationid=ZIP:{target_zip}'

    response = requests.get(api_url, headers=HEADERS)
    data = json.loads(response.text)

    # 容错处理:无结果时返回结构正确的空DataFrame
    if 'results' not in data:
        return pd.DataFrame(columns=[
            'elevation', 'mindate', 'maxdate', 'latitude', 
            'name', 'datacoverage', 'id', 'elevationUnit', 'longitude'
        ])

    results = data['results']
    df = pd.DataFrame(results)
    df['name'] = df['name'].astype(str)
    
    return df

def get_output_schema():
    # 修正数据类型映射,移除重复列
    return pd.DataFrame({
        'elevation': prep_decimal(),
        'mindate': prep_date(),
        'maxdate': prep_date(),
        'latitude': prep_decimal(),
        'name': prep_string(),
        'datacoverage': prep_decimal(),
        'id': prep_string(),
        'elevationUnit': prep_string(),
        'longitude': prep_decimal()
    })

# 将函数注册到TabPy服务器(根据你的TabPy地址调整端口)
client = Client('http://localhost:9004')
client.register(
    'get_stations_for_zip',
    get_stations_for_zip,
    '根据邮政编码返回NOAA气象站列表',
    schema=get_output_schema()
)

关键修复说明

  • 移除全局变量:函数内部独立创建并返回DataFrame,避免作用域冲突
  • 正确注册函数:使用TabPy Client将函数注册为服务,让Tableau Prep可以正常调用
  • 修正Schema类型:确保每个列的prep_*类型与实际数据匹配,移除重复列
  • 增加容错机制:接口无结果时返回结构正确的空DataFrame,避免Prep报错
  • 支持动态传参:允许传入自定义邮政编码,适配Tableau Prep的参数调用场景

内容的提问来源于stack exchange,提问作者mxs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 16:20:33