Python / SQL: thay thế các chuỗi trống của DataFrame bằng giá trị “Null” để chèn dữ liệu vào cơ sở dữ liệu

Nov 29 2020

Giả sử rằng tôi có khung dữ liệu này:

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})

Tôi gặp sự cố về định dạng để chèn loại dữ liệu này vào cơ sở dữ liệu của mình. Các cột "Débit", "Crédit", "Montant" được xác định để lấy float làm dữ liệu. Tuy nhiên, dữ liệu của các cột này không chỉ là số nguyên, tôi cũng có các chuỗi trống và đó là vấn đề của tôi. Tôi biết rằng tôi phải viết một điều kiện thay thế chuỗi trống bằng giá trị "Null" ở định dạng SQL, tuy nhiên tôi không biết cách thực hiện điều đó trong python hoặc trong SQL. Tôi đang khám phá / học hỏi môi trường SQL.

Đây là mã của tôi:

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()

Ai đó làm ơn giúp tôi với.

Cảm ơn bạn

Trả lời

1 Parfait Nov 30 2020 at 02:13

Dường như bạn đang trộn các loại trong khung dữ liệu Pandas nơi chuỗi '', được kết hợp với số nguyên trong cùng một cột như được chứng minh bởi tất cả các objectloại. Trong cơ sở dữ liệu quan hệ, bạn không thể kết hợp các kiểu dữ liệu. Và chuyển đổi ''thành chuỗi 'NULL'sẽ không giải quyết được vấn đề của bạn. Trong SQL,NULL <> 'NULL'

df.dtypes

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

Do đó, hãy chuyển đổi cột thành số với pd.to_numericchuỗi trống '', chuyển đổi NaNmà thực thể này sẽ dịch sang NULLthực thể SQL .

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

Sau đó chạy truy vấn của bạn. Trên thực tế, hãy tránh forvòng lặp chậm hơn với iterrowsvà xem xét 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

Bạn có thể sử dụng Pandas.DataFrame.to_sqlchẳng hạn như

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

trong đó appendtùy chọn là viết tắt của việc chèn các giá trị mới vào bảng, nếu phiên bản gấu trúc là 0,15+

DaniMesejo Nov 29 2020 at 21:30

Bạn có thể làm:

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)

Đầu ra

      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

Hoặc đơn giản,

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

Đầu ra

      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

Chuyển đổi sang numericcác cột tương ứng vàfillna(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