【问题标题】:Inserting JSON as string to mysql fails in Python在 Python 中将 JSON 作为字符串插入 mysql 失败
【发布时间】:2022-01-18 23:11:16
【问题描述】:

我正在尝试使用插入查询将一些数据更新到 python 中的 mysql。如果我传入字符串,它工作正常并更新数据库中的数据。但是,当我尝试将 JSON 作为字符串添加到查询时,它给了我语法错误。这是我正在做的事情和输出。

check = process_quote(json_data)
 # check returns a json.dumps(jsonVal) as a string
update_job_status(job_id, consts.COMPLETED_STATUS, check)


# update mysql table
def update_job_status(job_id, target_status, result):
    c_mysql = create_mysql()
    mysql_dict = {"request_result": target_status, "request_ID": job_id, "result": result}
    c_mysql.insert_row(consts.MYSQL_TABLE, mysql_dict)

def insert_row(self, table_name, row_obj):

        keys = row_obj.keys()
        print("the Keys are : ")
        print(keys)
        values = map(lambda v: self.sql_quote_col(row_obj[v]), keys)
        update_values = map(lambda v: "%s=VALUES(%s)" % (v, v), keys)
        print(list(update_values))
        sql = """INSERT IGNORE INTO {database_name}.{table_name} ({column_names}) VALUES ({column_values});""".format(database_name=consts.databaseNAME,table_name=table_name,column_names=", ".join(keys),column_values=", ".join(values))
        # logging.debug(sql)
        print(sql)
        self.write_query(sql)



def sql_quote_col(self, val):
        if type(val) is str:
            return "\"%s\"" % val
        elif val is None:
            return "NULL"
        else:
            return "%s" % str(val)

def write_query(self, sql):
        logging.info(sql)
        self.writeDb = self.connect()
        cursor = self.writeDb.cursor()
        # try:
        cursor.execute(sql)
        # except:
        #     logging.error("sql query execution fails: %s" % sql)
        cursor.close()
        self.writeDb.commit()
        self.writeDb.close()

当我尝试通过打印语句来识别查询时,我发现了 json 元素出现双 "" 的问题。查询看起来像:

INSERT IGNORE INTO databasename.tablename (request_result, request_ID, result) VALUES ("completed", "id_val", ""{\"First Name\":\"value\",\"Middle Initial\":\"E\",\"Last Name\":\"Testing\",\"value\":\"somevalue\"}"");

我可以理解问题在于双引号,但我无法确定为什么有 2 个引号添加到相同的引号中。任何帮助/指针将不胜感激。

谢谢

【问题讨论】:

  • 您的代码没有足够的信息来提供一个好的答案 - 解决方案不是将值粘贴到查询中,而是将 ? 放在一个值所在的位置,然后传递替换到运行查询的实际方法 - 但您没有共享该代码(即.write_query),也没有共享定义值的代码,例如column_names。这既解决了您的问题,又有助于防止 SQL 注入问题。
  • @Grismar 我已经分享了@98​​7654326@ 函数。 SQL 查询存在于insert_row 中。列的定义是使用update_job_status 中的字典完成的。我已经粘贴了所有用于实现相同功能的功能。我不明白你在说什么功能。

标签: python mysql


【解决方案1】:

您当前的解决方案对 SQL 注入开放,并且解决该问题也解决了您的格式问题。

如果您多次调用write_query,您可能希望重复使用该连接,而不是每次调用时都创建一个新连接。但是,只需使用您所拥有的,这就是如何更改write_query

变化:

def write_query(self, sql, values):
    self.writeDb = self.connect()
    cursor = self.writeDb.cursor()
    cursor.execute(sql, tuple(*values))
    self.writeDb.commit()
    self.writeDb.close()

你在哪里称呼它:

        sql = """INSERT IGNORE INTO {database_name}.{table_name} ({column_names}) VALUES ({column_values});""".format(database_name=consts.databaseNAME, table_name=table_name, column_names=", ".join(keys), column_values=", ".join(['?' for __ in keys]))
        self.write_query(sql, values)

请注意,我无法真正测试我在这里写的内容,因为您没有提供一个最小的、可重现的示例,但我认为这里的想法应该很清楚。

一般来说,不要这样做:

sql = 'SELECT * FROM table WHERE field = "value"'
conn.execute(sql)

你应该这样做:

sql = 'SELECT * FROM table WHERE field = ?'
conn.execute(sql, (value,))

【讨论】:

    猜你喜欢
    • 2016-06-30
    • 2022-07-28
    • 2017-05-14
    • 2022-08-14
    • 1970-01-01
    • 2018-05-14
    • 2021-07-16
    • 1970-01-01
    • 2011-07-05
    相关资源
    最近更新 更多