如何将MySQL查询结果按status分组存入Python字典(Ansible场景)
解决Ansible动态清单按MySQL表status分组的问题
我来帮你搞定这个需求!既然你已经能通过Python查询到MySQL里的IP和status数据,接下来只需要两步:把数据按status分组存入字典,再转换成Ansible能识别的动态清单格式就行。
第一步:构建按status分组的IP字典
假设你从MySQL查询到的数据是类似这样的元组列表(每个元组对应一条(ip, status)记录):
db_results = [("1.1.1.1", 23), ("2.2.2.2", 21), ("3.3.3.3", 23), ("4.4.4.4", 23), ("5.5.5.5", 21)]
我们可以用defaultdict来自动初始化空集合,遍历查询结果把每个IP归类到对应status的分组里(用集合是为了自动去重,最后转成列表适配JSON格式):
from collections import defaultdict # 用defaultdict自动创建空集合作为默认值 grouped_hosts = defaultdict(set) for ip, status in db_results: grouped_hosts[status].add(ip) # 把集合转成列表(JSON不支持集合类型) for key in grouped_hosts: grouped_hosts[key] = list(grouped_hosts[key])
这时候grouped_hosts就会是你想要的结构:
{21: ["2.2.2.2", "5.5.5.5"], 23: ["1.1.1.1", "3.3.3.3", "4.4.4.4"]}
第二步:转换成Ansible动态清单格式
Ansible的动态清单需要输出特定的JSON结构,核心是每个组包含hosts列表,还可以通过_meta字段存储主机变量(如果有需要的话)。
把上面的分组字典转换成Ansible清单结构的代码如下:
import json # 初始化清单基础结构 inventory = { "_meta": { "hostvars": {} # 若要给主机添加变量,可在这里配置,比如{"1.1.1.1": {"ansible_user": "root"}} } } # 将分组数据注入清单 for status, hosts in grouped_hosts.items(): # 把status转成字符串作为组名(Ansible组名建议用字符串格式) group_name = f"status_{status}" inventory[group_name] = { "hosts": hosts } # 打印JSON格式的结果,这就是Ansible能识别的动态清单 print(json.dumps(inventory, indent=2))
完整可运行的脚本示例
把查询MySQL、分组、生成清单的逻辑整合到一起,这里用mysql.connector库做演示(如果用pymysql,只需要替换数据库连接部分):
#!/usr/bin/env python3 import json from collections import defaultdict import mysql.connector def get_mysql_data(): # 替换成你的MySQL连接信息 conn = mysql.connector.connect( host="your_mysql_host", user="your_db_user", password="your_db_password", database="your_db_name" ) cursor = conn.cursor() # 替换成你的表名和字段名 cursor.execute("SELECT ip, status FROM your_host_table") results = cursor.fetchall() cursor.close() conn.close() return results def generate_ansible_inventory(): db_results = get_mysql_data() grouped_hosts = defaultdict(set) for ip, status in db_results: grouped_hosts[status].add(ip) # 集合转列表适配JSON for key in grouped_hosts: grouped_hosts[key] = list(grouped_hosts[key]) inventory = { "_meta": {"hostvars": {}} } for status, hosts in grouped_hosts.items(): group_name = f"status_{status}" inventory[group_name] = {"hosts": hosts} print(json.dumps(inventory, indent=2)) if __name__ == "__main__": generate_ansible_inventory()
使用注意事项
- 给脚本添加可执行权限:
chmod +x mysql_inventory.py - 先测试脚本输出是否正常:
./mysql_inventory.py - 在Ansible中使用该动态清单:
ansible all -i mysql_inventory.py -m ping
这样就能完美实现你想要的按status分组的Ansible动态清单啦!
内容的提问来源于stack exchange,提问作者Diler Singh
相关产品推荐
相关产品推荐

