【问题标题】:Python/ SQL : replacing the empty strings of a DataFrame by a "Null" value to insert the data in a databasePython / SQL:用“Null”值替换DataFrame的空字符串以将数据插入数据库
【发布时间】:2021-03-11 21:20:01
【问题描述】:

假设我有这个数据框:

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”值替换空字符串,但是我不知道如何在 python 或 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()

任何人都可以帮助我。

谢谢

【问题讨论】:

    标签: python sql pandas pyodbc


    【解决方案1】:

    将相应的列转换为numericfillna(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
    

    【讨论】:

      【解决方案2】:

      您似乎在 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 将列转换为数字,其中空字符串'' 转换为NaN,该实体应将其转换为SQL 的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_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()
      

      【讨论】:

      • 感谢@Parfait 的帮助,这正是我想要的。但是我仍然不能说它有效,因为我有一个我不明白的新错误:“传入的表格数据流(TDS)远程过程调用(RPC)协议流不正确。参数9(“”): “我的数据框实际上有 9 列,我已将这些列定义为在数据库中获取 (float,null)
      • 听起来您没有正确转换所需的列,因为空字符串仍然呈现。您可以发布 9 列而不是 5 列的数据框示例吗?另外,您是否正在调整 SQL 语句的插入列?添加/删除列时,尽量与此答案保持一致。请发布您的尝试。
      • 谢谢,你在这个新帖子中找到它:stackoverflow.com/questions/65080139/… 如果你能帮助我,我将不胜感激
      • 从技术上讲,您的问题是这个问题的副本,这没有解决。但我看到你有答案了。
      • 查看我的编辑,使用 DataFrame.where 将剩余的 NaN 转换为 None
      猜你喜欢
      • 2021-03-12
      • 1970-01-01
      • 2016-01-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多