首页 > 解决方案 > 将 pandas 数据帧转换为 .hyper 提取

问题描述

我在 pandas 数据框中有一个 SQL 输出,我想先将其转换为 .hyper Tableau 数据提取,然后通过 Extract API 发布到 Tableau 服务器。当我运行我的代码(如下)时,我收到错误消息:'module' object is not callable for tdefile = tableausdk.HyperExtract(outfilename)。我相信我的代码是正确的,但也许模块安装不正确?有没有人看到这个错误?

print("Importing modules...")

import pandas as pd
import pyodbc
import re
import numpy as np
import cx_Oracle
import smtplib
import schedule
import time
import win32com.client as win32
import tableauserverclient as TSC
import os
import tableausdk

from pandleau import *
from tableausdk import *
from tableausdk.HyperExtract import *

print("Done importing modules.")

server = x
db = y
conn_sql = pyodbc.connect(#fill in your connection data)

### sql query  - change from getdate() - 4 to TD# ##

sql_1 = """

        select 
        * from test

        """

df = pd.read_sql_query(sql_1, conn_sql)
df.head()

def job(df, outfilename):

    if os.path.isfile(outfilename):
        os.remove(outfilename)
        os.remove('DataExtract.log')

    try:  
        tdefile = tableausdk.HyperExtract(outfilename) 
    except:
        #os.remove(outfilename)
        os.system('del ' + outfilename)
        os.system('del DataExtract.log') 
        tdefile = tableausdk.HyperExtract(outfilename)
    # define the table definition
    tableDef = tableausdk.TableDefinition()

    # create a list of column names
    colnames = df.columns
    # create a list of column types
    coltypes = df.dtypes

    # create a dict for the field maps
    # Define type maps
    # Caveat: I am not including all of the possibilities here
    fieldMap = { 
        'float64' :     tde.Types.Type.DOUBLE, 
        'float32' :     tde.Types.Type.DOUBLE,
        'int64' :       tde.Types.Type.DOUBLE,
        'int32' :       tde.Types.Type.DOUBLE,
        'object':       tde.Types.Type.UNICODE_STRING,
        'bool' :        tde.Types.Type.BOOLEAN,
        'datetime64[ns]': tde.Types.Type.DATE,
    }

    # for each column, add the appropriate info the Table Definition
    for i in range(0, len(colnames)):
        cname = colnames[i] #header of column
        coltype = coltypes[i] #pandas data type of column
        ctype = fieldMap.get(str(coltype)) #get integer field type in Tableau Speak
        tableDef.addColumn(cname, ctype)


    # add the data to the table
    with tdefile as extract:
        table = extract.addTable("Extract", tableDef)
        for r in range(0, df.shape[0]):
            row = tde.Row(tableDef)

            for c in range(0, len(coltypes)):
                if df.iloc[r,c] is None: 
                    row.setNull(c)
                elif str(coltypes[c]) in ('float64', 'float32', 'int64', 'int32'):
                    try:                    
                        row.setDouble(c, df.iloc[r,c])
                    except:
                        row.setNull(c)
                elif str(coltypes[c]) == 'object':
                    try:                    
                        row.setString(c, df.iloc[r,c]) 
                    except:
                        row.setNull(c)
                elif str(coltypes[c]) == 'bool':
                    row.setBoolean(c, df.iloc[r,c])
                elif str(coltypes[c]) == 'datetime64[ns]':
                    try:                    
                        row.setDate(c, df.iloc[r,c].year, df.iloc[r,c].month, df.iloc[r,c].day )
                    except:
                        row.setNull                        
                else:
                    row.setNull(c)
            # insert the row
            table.insert(row)

    tdefile.close()



    #df_tableau = pandleau(df_1)

    #df_tableau.set_spatial('SpatialDest', indicator=True)

    #df_tableau.to_tableau('test.hyper', add_index=False)

job(df, 'test_1.hyper')

标签: pythonpandas

解决方案


推荐阅读