Python / SQL: Ersetzen der leeren Zeichenfolgen eines DataFrame durch einen Nullwert, um die Daten in eine Datenbank einzufügen
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
Sie scheinen Typen im Pandas-Datenrahmen zu mischen, wobei Zeichenfolge, ''
mit Ganzzahl in derselben Spalte kombiniert wird, wie von allen object
Typen 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_numeric
wobei leere Zeichenfolgen ''
konvertieren, in NaN
die diese Entität in die SQL- NULL
Entitä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 for
Schleife mit iterrows
und 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()
Sie können Pandas.DataFrame.to_sql
wie verwenden
df.to_sql('dbo.tbl_data_xml', con=connection, if_exists='append', index=False )
Dabei append
steht die Option für das Einfügen neuer Werte in die Tabelle, wenn die Pandas-Version 0.15+ ist
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
In numeric
die 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