![](/img/trans.png)
[英]Python MySQL queries time out where MySQL workbench works fine
[英]Stored procedure works on MySQL workbench, but not in python
我正在测试一个数据库,其中有3个表,第1个表存储用户信息,第2个表存储不同城市的纬度和经度,还有第三个表存储用户的位置及其到最近城市的距离。 第三个表具有来自其他两个表的主键的组合键。 我已经在mysql工作台中编写了一个存储过程,该存储过程接受5个变量,然后将数据插入到第3个表中,这是使用一些随机变量的代码:
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调用该过程时,它会引发错误:“键'PRIMARY'的条目'70440675-883'重复”。 因此,似乎它试图插入到表中,但是并没有保存它! 有人可以告诉我我在做什么错吗?
我的猜测是,存储过程的第二和第三查询之间可能存在一些舍入问题。 您可能会考虑完全消除第二个查询,而只是将第三个查询更改为以下内容:
SELECT location_id, ST_Distance_Sphere(@pt1, geopoint)/1000 AS distance
INTO @lmini, @mini
FROM locations
ORDER BY distance ASC
LIMIT 1;
*之所以说“类似”,是因为我最近主要在MSSQL中工作,而在我更频繁地使用MySQL时,并没有做很多SELECT INTO操作。 (具体来说,我不记得您是否可以使用别名和类似的名称。)
回答----- >>,所以最终我能够使它工作,诀窍是在我从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))
在文档中没有提到在使用.callproc()方法之后我们需要使用.commit() ,特别是当所有更新和插入都在数据库端完成时。 但是, .commit()文档中提到
由于默认情况下Connector / Python不会自动提交,因此在每次修改使用事务存储引擎的表的数据的事务之后,调用此方法很重要。
所以我的猜测是,由于该过程试图处理数据库上的数据,并且是从python客户端调用的,因此在使用.callproc()之后,我们需要使用.commit()。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.