2015-12-20 19 views
9

Ho un dataframe panda creato dinamicamente con nomi di colonne diversi. Sto cercando di inviarli a sql, ma non voglio che vadano a mssqlserver come il tipo di dati predefinito "text" (qualcuno può spiegare perché questo è l'impostazione predefinita? Non avrebbe senso usare un tipo di dati più comune?)panda a_sql tutte le colonne come nvarchar

Qualcuno sa come posso specificare un tipo di dati per tutte le colonne?

column_errors.to_sql('load_errors',push_conn, if_exists = 'append', index = False, dtype = #Data type for all columns#) 

l'argomento DTYPE prende un dict, e dato che non so quali saranno le colonne è difficile impostare tutti loro di essere 'sqlalchemy.types.NVARCHAR'

Questo è ciò che vorrebbe fare:

column_errors.to_sql('load_errors',push_conn, if_exists = 'append', index = False, dtype = 'sqlalchemy.types.NVARCHAR') 

Qualsiasi aiuto/comprensione del modo migliore per specificare tutti i tipi di colonna sarebbe molto apprezzato!

+1

Per coloro che sono googling ora, voglio dire che questa sintassi desiderabile è stata implementata – Liza

risposta

17

È possibile creare questo dict dinamicamente se non si conoscono i nomi delle colonne di anticipo:

from sqlalchemy.types import NVARCHAR 
df.to_sql(...., dtype={col_name: NVARCHAR for col_name in df}) 

Nota che si deve passare l'oggetto di tipo sqlalchemy stessa (o un'istanza per specificare i parametri come NVARCHAR(length=10)) e non una stringa come nell'esempio.

+0

Grazie, bel trucco - avrei dovuto pensarci! Vorrei che ci fosse una funzione nativa per farlo - sarebbe bello se l'argomento dtype riconoscesse un tipo passato come il dtype per tutte le colonne, mentre un dict era per le specifiche colonne menzionate. – flyingmeatball

+0

@flyingmeatball Sarebbe difficile aggiungere, penso, ho aperto una richiesta di miglioramento: https://github.com/pydata/pandas/issues/11886 – joris

10

Per utilizzare dtype, passare un dizionario con chiave a ciascuna colonna del frame di dati con il corrispondente sqlalchemy types. Cambiare le chiavi di effettivi nomi delle colonne della struttura dei dati:

import sqlalchemy 
import pandas as pd 
... 

column_errors.to_sql('load_errors',push_conn, 
         if_exists = 'append', 
         index = False, 
         dtype={'datefld': sqlalchemy.DateTime(), 
          'intfld': sqlalchemy.types.INTEGER(), 
          'strfld': sqlalchemy.types.NVARCHAR(length=255) 
          'floatfld': sqlalchemy.types.Float(precision=3, asdecimal=True) 
          'booleanfld': sqlalchemy.types.Boolean}) 

Si può anche essere in grado di creare in modo dinamico questo dtype dizionario dato che non conosci i nomi delle colonne o tipi di anticipo:

def sqlcol(dfparam):  

    dtypedict = {} 
    for i,j in zip(dfparam.columns, dfparam.dtypes): 
     if "object" in str(j): 
      dtypedict.update({i: sqlalchemy.types.NVARCHAR(length=255)}) 

     if "datetime" in str(j): 
      dtypedict.update({i: sqlalchemy.types.DateTime()}) 

     if "float" in str(j): 
      dtypedict.update({i: sqlalchemy.types.Float(precision=3, asdecimal=True)}) 

     if "int" in str(j): 
      dtypedict.update({i: sqlalchemy.types.INT()}) 

    return dtypedict 

outputdict = sqlcol(df)  
column_errors.to_sql('load_errors', 
        push_conn, 
        if_exists = 'append', 
        index = False, 
        dtype = outputdict) 
+0

Grazie, funziona ma speravo che esistesse un modo più semplice di fare nel singolo comando to_sql che stavo già usando. – flyingmeatball

Problemi correlati