MySQL临时表在Python调用过程中的生命周期
1. 需求
在MySQL数据库中,通过存储过程调用,查询结果集放在一个临时表中,提供给Python使用。临时表的会话周期在Python有效期是由db对象还是cursor对象决定的。
2.存储过程
把用户信息放在临时表中,通过参数定义临时表名。
CREATE DEFINER=`root`@`%` PROCEDURE `pro_temp_life`(in tablename varchar(20),out v_result int )
begin
set @sql_txt = concat('create temporary table ',tablename,' as select user, host from mysql.user;');
-- 动态构建的SQL语句
prepare pre_sql from @sql_txt;
-- 执行准备好的查询
execute pre_sql;
set @sql_txt = concat('select count(*) into @tmp_count from ',tablename,' ;') ;
-- 动态构建的SQL语句
prepare pre_sql from @sql_txt;
-- 执行准备好的查询
execute pre_sql;
set v_result = @tmp_count;
-- 释放查询语句对象资源
deallocate prepare pre_sql;
end
3.Python 调用测试
(1)测试情况1
global_db = pymysql.connect(**common_env.global_config)
global_cursor = global_db.cursor()
# [0]参数1 [1]参数2
condition=['TcbRWFwG',0]
global_cursor.callproc('pro_temp_life', condition)
print('condition:',condition[1])
global_cursor.execute('select * from ' + condition[0] + ';')
result = global_cursor.fetchall()
for r in result :
print(r)
global_cursor.close()
global_db.close()
执行结果:
condition: 0
('root', '%')
('mysql.infoschema', 'localhost')
('mysql.session', 'localhost')
('mysql.sys', 'localhost')
('root', 'localhost')
说明:
没有能返回存储过程的返回值,是因为pymysql 模块的原因。再以前的文章中测试验证过,不做赘述。
在cursor调用存储过程后,再执行select ,临时表在MySQL数据库的会话中存在。
(2)测试情况2
global_db = pymysql.connect(**common_env.global_config)
global_cursor = global_db.cursor()
# [0]参数1 [1]参数2
condition=['TcbRWFwG',0]
global_cursor.callproc('pro_temp_life', condition)
print('condition:',condition[1])
global_cursor.execute('select * from ' + condition[0] + ';')
result = global_cursor.fetchall()
for r in result :
print(r)
# 关闭cursor
global_cursor.close()
global_cursor = global_db.cursor()
global_cursor.execute('select * from ' + condition[0] + ';')
result = global_cursor.fetchall()
for r in result :
print(r)
global_db.close()
结果:
condition: 0
('root', '%')
('mysql.infoschema', 'localhost')
('mysql.session', 'localhost')
('mysql.sys', 'localhost')
('root', 'localhost')
('root', '%')
('mysql.infoschema', 'localhost')
('mysql.session', 'localhost')
('mysql.sys', 'localhost')
('root', 'localhost')
说明:
关闭curosr后,再次打开cursor ,查询临时表,临时表还存在,说明会话生命周期比cursor长。
(3)测试情况3
global_db = pymysql.connect(**common_env.global_config)
global_cursor = global_db.cursor()
# [0]参数1 [1]参数2
condition=['TcbRWFwG',0]
global_cursor.callproc('pro_temp_life', condition)
print('condition:',condition[1])
global_cursor.execute('select * from ' + condition[0] + ';')
result = global_cursor.fetchall()
for r in result :
print(r)
# 关闭cursor db
global_cursor.close()
global_db.close()
global_db = pymysql.connect(**common_env.global_config)
global_cursor = global_db.cursor()
global_cursor.execute('select * from ' + condition[0] + ';')
result = global_cursor.fetchall()
for r in result :
print(r)
global_db.close()
结果:
condition: 0
('root', '%')
('mysql.infoschema', 'localhost')
('mysql.session', 'localhost')
('mysql.sys', 'localhost')
('root', 'localhost')
ProgrammingError: (1146, "Table 'mysql.TcbRWFwG' doesn't exist")
4. 结论
MySQL的临时表的生命周期,在Python调用过程中,可以看到MySQL临时表生命周期是和db对象一致,如果db对象关闭后,临时表也就不存在了。如果db对象不关闭,只关闭cursor对象,再次打开cursor ,MySQL的会话没有结束,临时表对象还存在。