Python / SQL : DataFrame의 빈 문자열을 "Null"값으로 대체하여 데이터베이스에 데이터 삽입

Nov 29 2020

이 데이터 프레임이 있다고 가정 해 봅시다.

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

내 데이터베이스에 이러한 종류의 데이터를 삽입하는 형식에 문제가 있습니다. "Débit", "Crédit", "Montant"열은 부동 소수점을 데이터로 가져 오도록 정의됩니다. 그러나 이러한 열의 데이터는 정수일뿐만 아니라 빈 문자열도 있으며 이것이 내 문제입니다. 빈 문자열을 SQL 형식의 "Null"값으로 바꾸는 조건을 작성해야한다는 것을 알고 있지만 파이썬이나 SQL에서 어떻게해야할지 모르겠습니다. SQL 환경을 발견 / 배우고 있습니다.

내 코드는 다음과 같습니다.

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

누구든지 나를 도울 수 있습니다.

감사합니다

답변

1 Parfait Nov 30 2020 at 02:13

Pandas 데이터 프레임에서 유형을 혼합하는 것으로 보입니다. 여기서 문자열 ''은 모든 object유형에서 입증 된 것과 동일한 열에서 정수와 결합됩니다 . 관계형 데이터베이스에서는 데이터 유형을 혼합 할 수 없습니다. 그리고 ''문자열 로 변환 'NULL'해도 문제가 해결되지 않습니다. SQL에서NULL <> 'NULL'

df.dtypes

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

따라서 열을 숫자로 변환하십시오. pd.to_numeric여기서 빈 문자열 은이 엔티티가 SQL 엔티티 ''로 변환 NaN되어야하는 대상으로 변환됩니다 NULL.

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

그런 다음 쿼리를 실행하십시오. 사실, 더 느린 for루프를 피하고 +를 iterrows고려하십시오 .df.to_numpycursor.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

다음 Pandas.DataFrame.to_sql과 같이 사용할 수 있습니다.

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

여기서 append옵션은 pandas 버전이 0.15+ 인 경우 테이블에 새 값을 삽입하는 것을 나타냅니다.

DaniMesejo Nov 29 2020 at 21:30

다음과 같이 할 수 있습니다.

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)

산출

      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

또는 간단히

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

산출

      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

numeric각 열로 변환 하고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