python - 存储过程适用于 MySQL 工作台,但不适用于 python

标签 python mysql mysql-python

我正在测试一个数据库,其中有 3 个表,第 1 个表存储用户信息,第 2 个表存储不同城市的纬度和经度,第 3 个表存储用户的位置及其到最近的城市。第三个表有一个来自其他两个表的主键的组合键。 我在 mysql workbench 中编写了一个存储过程,它接受 5 个变量,然后将数据插入到第三个表中,这里是使用一些随机变量的代码:

SET @lat55 = 36.8451995849609;
SET @lng55 = 54.428798675537;
SET @city55 = 'Rasht';
SET @state55 = 'Gilan';
SET @user_id55 = 70440675;


DELIMITER //  
DROP PROCEDURE IF EXISTS do1 //
CREATE PROCEDURE do1 (IN id INT, IN state VARCHAR(25), IN city VARCHAR(25),             
IN lat DECIMAL(15,13),IN lng DECIMAL(15,12))
BEGIN

`  `DECLARE dmini DECIMAL(5,1);
    DECLARE lmini INT;

    SELECT location_id, ST_Distance_Sphere(POINT(lng,lat), geopoint)/1000 AS 
    distance INTO lmini, dmini FROM locations ORDER BY distance ASC LIMIT 1;

    INSERT INTO user_has_loc (user_id, location_id, distance, state, city, 
    lat, lng) VALUES (id, lmini, dmini, state, city, lat, lng);
END;
//

CALL do1(@user_id55,@state55,@city55,@lat55,@lng55);

它工作得很好并插入到表中,但是当我尝试从 python 中使用相同的变量调用相同的过程时,它什么也不做:

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="root",
        password="123456",
        database="v21")
    c = mydb.cursor()

    lat = 36.8451995849609
    lng = 54.428798675537
    city = "Rasht"
    state = "Gilan"
    user = 70440675

    arg = (user, state, city, lat, lng)

    c.callproc('do1', arg)

except mysql.connector.Error as err:
    print("Something went wrong: {}".format(err))

这是当我使用

c.execute("CALL do1({},{},{},{},{})".format(user, state, city, lat, lng))

它给出了另一个错误,说“'字段列表'中的未知列'Gilan'”。有趣的是,如果我手动将相同的数据插入到表中,那么当我尝试从 python 调用该过程时,它会引发错误:“Duplicate entry '70440675-883' for key 'PRIMARY'”。所以它似乎试图插入到表中,但它没有保存它! 有人可以告诉我我在这里做错了什么吗??

最佳答案

回答 ----->> 所以最后我能够让它工作,诀窍是在我从 python 调用过程后添加 mydb.commit()

try:
    mydb = mysql.connector.connect(
        host="localhost",
        user="root",
        password="123456",
        database="v21")
    c = mydb.cursor()

    lat = 36.8451995849609
    lng = 54.428798675537
    city = "Rasht"
    state = "Gilan"
    user = 70440675

    arg = (user, state, city, lat, lng)

    c.callproc('do1', arg)
    mydb.commit()

except mysql.connector.Error as err:
    print("Something went wrong: {}".format(err))

文档中没有提到我们需要在使用 .commit() 方法后使用 .callproc() ,特别是当所有更新和插入都在数据库端完成时。但是,在 .commit() 文档中提到

Since by default Connector/Python does not autocommit, it is important to call this method after every transaction that modifies data for tables that use transactional storage engines.

所以我的猜测是因为该过程试图操作数据库中的数据并且它是从 python 客户端调用的,所以我们需要在使用 .callproc() 之后使用 .commit()。

关于python - 存储过程适用于 MySQL 工作台,但不适用于 python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53751358/

相关文章:

mysql - ALTER 表 - 在 MySQL 中添加 AUTOINCREMENT

python MySQLdb : use ssl without certificate

python - Pandas 'read_csv' 仅在一个特定目录中给出错误

c# - Double 未正确存储在 MySQL 数据库中

python - 如何通过 SOAPPy (python) 或 SUDS 发送嵌套的 SOAP 请求

mysql - 是否可以将一个 mysql 表的列(结构和内容)附加到另一个?

python - mysql-python 连接器同时适用于 python2.7 和 3.4

mysql - Python 3 MySQL GPS跟踪器数据库插入错误

python - 调整扫描线填充以检测离散对象

python - NaNs 在 Numpy 中比较相等