Python mysql.connector cursor.lastrowid总是返回0

时间:2014-12-02 22:36:08

标签: python mysql stored-procedures

我正在使用Python 2.7的mysql.connector模块。我已将代码分解为最简单的脚本,但我仍然遇到此问题。问题是,当我尝试获取最后一行id(在MySQL中为LAST_INSERT_ID)时,无论插入多少行,都返回0。有没有人有这个问题的解决方案?

我的代码如下:

import mysql.connector
default_config = {
    'user': 'root',
    'password': 'password',
    'host': '127.0.0.1',
    'database': 'test',
    'raise_on_warnings': True,
    'autocommit': True
    }
connection = mysql.connector.connect(**default_config)
cursor = connection.cursor()
args = ('name', 'desc')
cursor.callproc('sp_tools_insert', args)
lastid = cursor.lastrowid
print lastid # This returns 0 every time, regardless of number of inserts

我的存储过程如下所示:

CREATE PROCEDURE `sp_tools_insert`
    (
        IN p_name VARCHAR(45), 
        IN p_description VARCHAR(255)
    )
BEGIN 
INSERT INTO TOOLS
    (
        tool_name, 
        description                   
    )
VALUES 
    ( 
        p_name, 
        p_description
    ); 
END

这就是我的TOOLS表的定义方式:

DROP TABLE IF EXISTS `test`.`TOOLS` ;

CREATE TABLE IF NOT EXISTS `test`.`TOOLS` (
  `id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
  `tool_name` VARCHAR(45) NOT NULL,
  `description` VARCHAR(255) NOT NULL,
  PRIMARY KEY (`id`))
ENGINE = InnoDB;

我已验证存储过程是否正常工作,.callproc()调用按预期工作。唯一不起作用的是.lastrowid电话。有什么建议吗?

2 个答案:

答案 0 :(得分:7)

lastrowid属性:

  

...返回先前INSERT或UPDATE语句为AUTO_INCREMENT列生成的值...

您还没有运行INSERTUPDATE声明,而是运行CALL声明。

要获取详细信息,您必须按照lastrowid调用的mysql_insert_id函数的C API文档链接。特别是:

  对于生成mysql_insert_id()值的存储过程,{p> CALLAUTO_INCREMENT语句后返回0,因为在这种情况下mysql_insert_id()适用于CALL而不是LAST_INSERT_ID()程序中的陈述。在该过程中,您可以在SQL级别使用AUTO_INCREMENT来获取TOOLS值。

我在此假设您的AUTO_INCREMENT表确实有lastrowid列;否则,你首先没有价值。

另外,请注意,这只是与您的断言相反的方式之一,LAST_INSERT_ID()和{{1}}不是同一回事。值得一读LAST_INSERT_ID的文档。

答案 1 :(得分:1)

@abarnert说.lastrowid无法正常工作的原因是我没有打电话给INSERTUPDATE,而是CALL 。因此,解决此问题的唯一方法是更改​​我的存储过程,如下所示:

CREATE PROCEDURE `sp_tools_insert`
    (
        IN p_name VARCHAR(45), 
        IN p_description VARCHAR(255)
    )
BEGIN 
INSERT INTO TOOLS
    (
        tool_name, 
        description                   
    )
VALUES 
    ( 
        p_name, 
        p_description
    )
SELECT LAST_INSERT_ID();
END

现在,当您调用该存储过程时,您应该期望它返回插入行的ID,方法与从调用{{1}的存储过程的任何调用返回变量的方式相同。声明。

在这个例子中:

SELECT

我仍然没有弄清楚为什么args = ('name', 'desc') cursor.callproc('sp_tools_insert', args) for result in cursor.stored_results(): print result.fetchall() # Or result.fetchone() for just the first result 甚至存在,因为它永远不会与.lastrowid.callproc()语句一起使用。如果有人对这个问题有任何见解,请告诉我!