【问题标题】:psycopg2 Syntax errors at or near "' '"psycopg2 在“''”处或附近出现语法错误
【发布时间】:2021-12-13 13:53:57
【问题描述】:

我有一个名为 Data2 的数据框,我希望将它的值放入 postgresql 表中。由于某些原因,我不能使用 to_sql,因为 Data2 中的某些值是 numpy 数组。

这是 Data2 的架构:

  cursor.execute(
    """
    DROP TABLE IF EXISTS Data2;
    CREATE TABLE Data2 (
          time timestamp without time zone,
          u bytea,
          v bytea,
          w bytea,
          spd bytea,
          dir bytea,
          temp bytea
    );
    """
  )

我的代码段:

  for col in Data2_mcw.columns:
    for row in Data2_mcw.index:
      value = Data2_mcw[col].loc[row]
      
      if type(value).__module__ == np.__name__:
        value = pickle.dumps(value)
      
      cursor.execute(
          """
          INSERT INTO Data2_mcw(%s)
          VALUES (%s)
          """
          ,
          (col.replace('\"',''),value)
      )

产生错误:

psycopg2.errors.SyntaxError: syntax error at or near "'time'"
LINE 2:           INSERT INTO Data2_mcw('time')

如何纠正这个错误?

任何帮助将不胜感激!

【问题讨论】:

    标签: python sql postgresql dataframe


    【解决方案1】:

    我发现这段代码有两个问题。

    第一个问题是您不能将绑定参数用于列名,只能用于值。 SQL 字符串中两个%s 占位符中的第一个无效。您必须使用字符串连接来设置列名,如下所示(假设您使用的是 Python 3.6+):

          cursor.execute(
              f"""
              INSERT INTO Data2_mcw({col})
              VALUES (%s)
              """,
              (value,))
    

    第二个问题是 SQL INSERT 语句插入一整行。它不会像您期望的那样将单个值插入到已经存在的行中。

    假设您的数据框 Data2_mcw 如下所示:

       a  b  c
    0  1  2  7
    1  3  4  9
    

    很明显,这个数据框有六个值。如果您要在此数据帧上运行您的代码,那么它将在您的数据库表中插入六行,每个值一行,并且您的表中的数据如下所示:

       a  b  c
       1
       3
          2
          4
             7
             9
    

    我猜您不希望这样:您希望您的数据库表包含以下两行:

       a  b  c
       1  2  7
       3  4  9
    

    您必须一次插入一整行,而不是一次插入一个值。这意味着您必须交换两个循环,预先构建一次 SQL 字符串,并在将一行传递给数据库之前收集一行的所有值。像下面这样的东西应该可以工作(请注意,我没有 Postgres 数据库来测试它):

    column_names = ",".join(Data2_mcw.columns)
    placeholders = ",".join(["%s"] * len(Data2_mcw.columns))
    sql = f"INSERT INTO Data2_mcw({column_names}) VALUES ({placeholders})"
    
    for row in Data2_mcw.index:
        values = []
        for col in Data2_mcw.columns:
          value = Data2_mcw[col].loc[row]
          
          if type(value).__module__ == np.__name__:
            value = pickle.dumps(value)
            
          values.append(value)
        
        cursor.execute(sql, values)
    

    【讨论】:

      猜你喜欢
      • 2020-08-29
      • 1970-01-01
      • 2020-08-20
      • 2018-04-21
      • 2020-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多