MySQL Python连接器不提交

时间:2016-04-14 00:51:35

标签: python mysql

我有这个功能,它应该接收json并将值存储在RDS MySQL数据库上。

def saveMetric(metrics):
    cnx     = RDS_Connect()
    cursor  = cnx.cursor()
    jsonMetrics = json.loads(metrics)
    #print type(jsonMetrics['Metrics'])
    # Every 2000 registries, the script will start overriding values
    persistance = 2000
    save_metrics_query = (
            "REPLACE INTO metrics "
            "SET metric_seq = (SELECT COALESCE(MAX(row_id), 0) %% %(persistance)d + 1 FROM metrics AS m), "
            "instance_id = \'%(instance_id)s\', "
            "service = \'%(service)s\' , "
            "metric_name = \'%(metric_name)s\', "
            "metric_value = %(metric_value)f"
           )
    for metric in jsonMetrics['Metrics']:
        formatData = {}
        formatData['persistance'] = persistance
        formatData['instance_id'] = arguments.dimensionValue
        formatData['service'] = jsonMetrics['Service']
        formatData['metric_name'] = metric
        formatData['metric_value'] = jsonMetrics['Metrics'][metric]

        print save_metrics_query % formatData

        try:
            cursor.execute(save_metrics_query, formatData, multi=True)
            logger('info','Metrics were saved successfully!')
            cnx.commit()
        except mysql.connector.Error as err:
            logger('error', "Something went wrong: %s" % err)
    cursor.close()
    cnx.close()

RDS_Connect()已经过测试,它运行正常。问题是在运行该功能后,数据不会保存到DB。我认为提交存在问题,但我没有看到任何错误或警告消息。如果我手动运行查询,则会存储数据。

以下是解析json后运行的查询:

REPLACE INTO metrics SET metric_seq = (SELECT COALESCE(MAX(row_id), 0) % 2000 + 1 FROM metrics AS m), instance_id = 'i-03932937bd67622c4', service = 'AWS/EC2' , metric_name = 'CPUUtilization', metric_value = 0.670000

如果有帮助,这是函数接收的json:

{
"Metrics": {
    "CPUUtilization": 1.33, 
    "NetworkIn": 46428.0, 
    "NetworkOut": 38772.0
}, 
"Id": "i-03932937bd67622c4", 
"Service": "AWS/EC2"
}

我很感激一些帮助。

问候!

更新:

我发现问题与查询模板上的格式代码有关。 我写了这样的函数:

def saveMetric(metrics):
    cnx     = RDS_Connect()
    jsonMetrics = json.loads(metrics)
    print json.dumps(jsonMetrics,indent=4)

    persistance = 2000
    row_id_query_template = "SELECT COALESCE(MAX(row_id), 0) % {} + 1 FROM metrics AS m"
    row_id_query = row_id_query_template.format(persistance)

    save_metrics_query = (
        "REPLACE INTO metrics "
        "SET metric_seq = (" + row_id_query + "),"
        "instance_id = %(instance_id)s,"
        "service = %(service)s,"
        "metric_name = %(metric_name)s,"
        "metric_value = %(metric_value)s"
       )

    for metric in jsonMetrics['Metrics']:
        formatData = {}
        formatData['instance_id'] = arguments.dimensionValue
        formatData['service'] = jsonMetrics['Service']
        formatData['metric_name'] = metric
        formatData['metric_value'] = jsonMetrics['Metrics'][metric]

        if arguments.verbose == True:
            print "Data: ",formatData
            print "Query Template: ",save_metrics_query.format(**formatData)

        try:
            cursor  = cnx.cursor()
            cursor.execute(save_metrics_query, formatData)
            logger('info','Metrics were saved successfully!')
            cnx.commit()
            cursor.close()
        except mysql.connector.Error as err:
            logger('error', "Something went wrong: %s" % err)

    cnx.close()

如您所见,我在外部格式化SELECT。我相信整个问题都是由于这一行:

"metric_value = %(metric_value)f"

我改为:

"metric_value = %(metric_value)s"

现在它有效。我认为格式错误,给出语法错误(因为我不知道如何从未抛出异常)。

感谢所有花时间帮助我的人!

2 个答案:

答案 0 :(得分:1)

我还没有真正使用过MySQL,但是docs似乎表明用multi = True调用cursor.execute只会返回一个迭代器。如果这是真的,那么它实际上不会插入任何东西 - 你需要在迭代器上调用.next()(或者只是迭代它)来实际插入记录。

它还继续建议不要使用multi=True的参数:

  

如果multi设置为True,则execute()能够执行操作字符串中指定的多个语句。它返回一个迭代器,用于处理每个语句的结果。但是,在这种情况下使用参数不能很好地工作,并且通常自己执行每个语句通常是个好主意。

tl; dr:删除该参数,默认为False。

答案 1 :(得分:0)

这是解决方案。我改变了:

"metric_value = %(metric_value)f"

要:

"metric_value = %(metric_value)s"

进行一些故障排除我在SQL上发现了语法错误。不知怎的,这个例外没有显示出来。