如何从SQL游标中分离经纬度值?Python MySQL场景实现方案
日出时间回填功能的可实现方案
核心认知纠偏
- 单游标即可覆盖读数据、写数据全流程,完全不需要开启多个游标
- 很多开发者会误以为需要对查询结果做字符串拆分,本质是对mysql.connector的返回结构不熟悉:每次查询返回的每一行记录,都是把SELECT后面的字段值按顺序组成一个元组,每个元素就是对应列的独立值,不存在把两个字段拼成一个字符串的情况,根本不需要额外拆分操作
- 原代码逻辑存在两处会导致功能失效的设计:
- 仅单次调用
fetchone(),只能获取结果集的第一条记录,且直接遍历返回的元组,会把lat、lng作为元组元素逐个打印,并非拿到了合并后的字符串值 - 查询语句仅选取lat、lng两个字段,没有携带可唯一标识记录的字段,后续回填日出时间时无法匹配到对应的数据行
- 仅单次调用
分步实现逻辑
- 修正数据库连接配置
可以直接在连接参数里指定database="test",省掉单独执行use test语句的步骤 - 优化查询语句
查询时带上能唯一定位记录的字段(优先用表的主键id,没有的话用city字段匹配),筛选出sunrise为空的待处理记录,不要只查lat、lng两个字段 - 读取结果集
用fetchall()一次性拿到所有待处理记录,每一行结果是一个元组,按位置直接取lat、lng的独立值即可,不需要额外拆分 - 拼接API请求地址
把拿到的lat、lng值直接嵌入到接口参数位置,发起请求获取对应城市的日出时间 - 数据回填
执行update语句,根据匹配字段把拿到的日出时间写入对应记录的sunrise字段,注意mysql.connector默认是事务模式,需要手动调用commit()才会真正把修改写入数据库
修正后可直接运行的参考代码
import mysql.connector import requests # 数据库连接初始化 mydb = mysql.connector.connect( host="localhost", port=3306, user="avila", password="123289", database="test" ) cursor = mydb.cursor() # 查询所有待填充日出时间的记录,带上城市名作为匹配标识 query_sql = "SELECT city, lat, lng FROM table_name WHERE sunrise = '' OR sunrise IS NULL" cursor.execute(query_sql) all_todo_records = cursor.fetchall() for record in all_todo_records: # 元组按位置直接取独立值,无需拆分操作 city = record[0] lat = record[1] lng = record[2] # 拼接日出时间API请求地址 request_url = f"https://api.sunrise-sunset.org/json?lat={lat}&lng={lng}" # 发起请求获取返回数据(可自行补充超时、异常捕获逻辑) response = requests.get(request_url, timeout=10).json() sunrise = response["results"]["sunrise"] # 回填对应记录的日出时间 update_sql = "UPDATE table_name SET sunrise = %s WHERE city = %s" cursor.execute(update_sql, (sunrise, city)) # 提交事务,让修改生效 mydb.commit() # 操作完成后释放资源 cursor.close() mydb.close()
注意:如果你的表有自增主键id,建议把查询和更新的匹配条件换成id字段,避免重名城市导致的更新错误。
内容的提问来源于stack exchange,提问作者Alivajorg
相关产品推荐
相关产品推荐

