将DICT无推送到SQL Null

时间:2019-03-03 02:31:29

标签: python postgresql sqlalchemy

我有这段代码:

def get_summary_data(self):
    summary_data = self.page_data.find('table', {'class': 'GroupBox1'})
    record = {}
    rows = summary_data.findAll('tr')
    for row in rows:
        fields = row.findAll('td')
        for field in fields:
            key = field.find(text=True, recursive=False).strip()
            value = field.find('strong').text.strip() if field.find('strong') else None
            value = value if value else None
            if key != '':
                record[self.configuration[key]] = value
    ins_qry = "INSERT INTO {tablename} ({columns}) VALUES {values};".format(
        tablename='rrc_completion_data.summarydata',
        columns=', '.join(record.keys()),
        values=tuple(record.values())
    )
    self.engine.execute(ins_qry)

生成的查询如下:

INSERT INTO rrc_completion_data.summarydata (Track_No, Status, Operator_Nm, Compl_Type, Field_Nm, Completion_Dt, Lease_Nm, Filing_Purpose, District_No, Well_Type, LeaseNo, County, Well_No, WellBore_Profile, API, WB_Compl_Type, DrilL_Permit_No, SL_Parent_Drill_Permit_No, Field_No, Horiz_Depth_Severance) VALUES ('2928', 'Work in Progress', 'WILLIAMS PROD. GULF COAST, L.P. (924558)', 'New Well', 'NEWARK, EAST (BARNETT SHALE)', '05/17/2010', 'DR. BOB SMITH A NORTH', 'Initial Potential', '09', 'Producing', None, 'DENTON', '10H', 'HORIZONTAL', '42-121-33861', None, '687311', None, '65280200', None);

如您所见,我试图将None值用作Null。但导致此错误:

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column "none" does not exist
LINE 1: ...A NORTH', 'Initial Potential', '09', 'Producing', None, 'DEN...

我想念什么?我的目的是在不存在任何数据库的数据库表中包含空值。

谢谢

1 个答案:

答案 0 :(得分:1)

问题的根源是使用字符串格式将值传递给SQL查询。 从不这样做。它将使您暴露于SQL注入之中。看来您将这些列列入了白名单,这很好,但是随后传递了包装在Python tuple中的值,并相信该字符串表示形式与SQL行构造的字符串表示形式匹配-这是不正确的,正如已经看到的那样与None值。问题的另一个来源是包含'字符的字符串。

相反,您应该在查询字符串中使用占位符,并让您的库处理将值传递给SQL:

columns = list(record.keys())
ins_qry = "INSERT INTO rrc_completion_data.summarydata ({columns}) VALUES ({placeholders})".format(
    columns=', '.join(columns),
    placeholders=', '.join([':' + c for c in columns])
)
self.engine.execute(text(ins_qry), record)