Python / SQL: Ersetzen der leeren Zeichenfolgen eines DataFrame durch einen Nullwert, um die Daten in eine Datenbank einzufügen

Nov 29 2020

Angenommen, ich habe diesen Datenrahmen:

REFERENCE = ["GZF882348G", "SFGUZBJLNJU", "FTLNGZ242112", "DFBHGVGHG543"]
IBAN = ["FR7343563", "FR4832545", "FR9858331", "FR2001045"]
DEBIT = [26, '', 856, '']
CREDIT = ['', 324, '', 876]
MONTANT = [641, 33, '', 968]

df = pd.DataFrame({'Référence' : REFERENCE, 'IBAN' : IBAN, 'Débit' : DEBIT, 'Crédit' : CREDIT, 'Montant' : MONTANT})

Ich habe ein Formatproblem beim Einfügen dieser Art von Daten in meine Datenbank. Die Spalten "Débit", "Crédit", "Montant" werden definiert, um Floats als Daten zu erhalten. Die Daten dieser Spalten sind jedoch nicht nur ganze Zahlen, ich habe auch leere Zeichenfolgen und das ist mein Problem. Ich weiß, dass ich eine Bedingung schreiben muss, die eine leere Zeichenfolge durch einen "Null" -Wert im SQL-Format ersetzt, aber ich weiß nicht, wie das in Python oder in SQL geht. Ich entdecke / lerne die SQL-Umgebung.

Hier ist mein Code:

import pandas as pd
import pyodbc 

server = '...'
database = '...'
username = '...' 
password = '...'
driver = '...'

connection = pyodbc.connect('DRIVER='+driver+';SERVER='+server+';PORT=1433;DATABASE='+database+';UID='+username+';PWD='+password)
cursor = connection.cursor()

for i, row in df.iterrows():


    sql_exe = "INSERT INTO dbo.tbl_data_xml (Réference,IBAN,Débit,Crédit,Montant) VALUES (?,?,?,?,?)"
    cursor.execute(sql_exe, tuple(row))
    
    connection.commit()

Jeder kann mir bitte helfen.

Vielen Dank

Antworten

1 Parfait Nov 30 2020 at 02:13

Sie scheinen Typen im Pandas-Datenrahmen zu mischen, wobei Zeichenfolge, ''mit Ganzzahl in derselben Spalte kombiniert wird, wie von allen objectTypen belegt. In relationalen Datenbanken können Sie keine Datentypen mischen. Durch die Konvertierung ''in eine Zeichenfolge 'NULL'wird Ihr Problem nicht behoben. In SQLNULL <> 'NULL'

df.dtypes

# Référence    object
# IBAN         object
# Débit        object
# Crédit       object
# Montant      object
# dtype: object

Konvertieren Sie daher Spalten in numerische Spalten, pd.to_numericwobei leere Zeichenfolgen ''konvertieren, in NaNdie diese Entität in die SQL- NULLEntität übersetzt werden soll.

df[['Débit', 'Crédit', 'Montant']] = df[['Débit', 'Crédit', 'Montant']].apply(pd.to_numeric)

df.dtypes
# Référence     object
# IBAN          object
# Débit        float64
# Crédit       float64
# Montant      float64
# dtype: object

df
#       Référence       IBAN  Débit  Crédit  Montant
# 0    GZF882348G  FR7343563   26.0     NaN    641.0
# 1   SFGUZBJLNJU  FR4832545    NaN   324.0     33.0
# 2  FTLNGZ242112  FR9858331  856.0     NaN      NaN
# 3  DFBHGVGHG543  FR2001045    NaN   876.0    968.0

Führen Sie dann Ihre Abfrage aus. Vermeiden Sie in der Tat die langsamere forSchleife mit iterrowsund berücksichtigen Sie df.to_numpy+ cursor.executemany.

# PREPARED STATEMENT
sql_exe = "INSERT INTO dbo.tbl_data_xml (Réference,IBAN,Débit,Crédit,Montant) VALUES (?,?,?,?,?)"

# CONVERT DATA TO LIST OF NUMPY ARRAYS
sql_data = df.where(pd.notnull(df), None).to_numpy().replace(.tolist()

# EXECUTE ACTION QUERY
cursor.executemany(sql_exe, sql_data)
connection.commit()
1 BarbarosÖzhan Nov 29 2020 at 21:32

Sie können Pandas.DataFrame.to_sqlwie verwenden

df.to_sql('dbo.tbl_data_xml', con=connection, if_exists='append', index=False )

Dabei appendsteht die Option für das Einfügen neuer Werte in die Tabelle, wenn die Pandas-Version 0.15+ ist

DaniMesejo Nov 29 2020 at 21:30

Du könntest es tun:

df.loc[df['Débit'].eq(''), 'Débit'] = 'NULL'
df.loc[df['Crédit'].eq(''), 'Crédit'] = 'NULL'
df.loc[df['Montant'].eq(''), 'Montant'] = 'NULL'

print(df)

Ausgabe

      Référence       IBAN Débit Crédit Montant
0    GZF882348G  FR7343563    26   NULL     641
1   SFGUZBJLNJU  FR4832545  NULL    324      33
2  FTLNGZ242112  FR9858331   856   NULL    NULL
3  DFBHGVGHG543  FR2001045  NULL    876     968

Oder einfach,

df[df[['Débit', 'Crédit', 'Montant']].eq('')] = "NULL"
print(df)

Ausgabe

      Référence       IBAN Débit Crédit Montant
0    GZF882348G  FR7343563    26   NULL     641
1   SFGUZBJLNJU  FR4832545  NULL    324      33
2  FTLNGZ242112  FR9858331   856   NULL    NULL
3  DFBHGVGHG543  FR2001045  NULL    876     968
wwnde Nov 29 2020 at 21:35

In numericdie entsprechenden Spalten und konvertierenfillna(NULL)

df[['Débit', 'Crédit', 'Montant']]=df.iloc[:,2:].apply(lambda x: pd.to_numeric(x).fillna('NULL'))



     Référence       IBAN Débit Crédit Montant
0    GZF882348G  FR7343563    26   NULL     641
1   SFGUZBJLNJU  FR4832545  NULL    324      33
2  FTLNGZ242112  FR9858331   856   NULL    NULL
3  DFBHGVGHG543  FR2001045  NULL    876     968