迭代PostgreSQL品牌列表生成aiogram内联按钮的字符串类型问题
问题:迭代数据库品牌列表时无法生成字符串类型的Inline按钮
我正在基于aiogram框架开发汽车租赁Telegram机器人,需要在子菜单中提供动态变化的汽车品牌选择按钮——因为车辆库的可用品牌会随时间更新,按钮数量得跟着数据库内容调整。
已知条件
- 机器人包含普通键盘菜单和Inline菜单
- 已关联可更新的PostgreSQL数据库
当前遇到的问题:从数据库获取品牌列表后,迭代生成Inline按钮时,品牌名没有被处理为字符串格式(比如代码中出现VW而非'VW'),导致创建按钮时类型不匹配,需要把每个品牌名转为'brand_name'格式的字符串。
原代码
# DB Connection try: connect = psycopg2.connect(database = 'car_rental', user = 'postgres', password = 'datapass') curs = connect.cursor() curs.execute("""SELECT DISTINCT brand FROM fleet WHERE category = 'economy'""") economy_brands_list = [x[0] for x in curs.fetchall()] except: print('oops. DB die') finally: curs.close() connect.close() # function to generate Inline buttons def economy_bt_generator(): # Function generates the amount of inline buttons (brands in this case) depends on DB condition final_expression = 'InlineKeyboardMarkup()' for variable in lst: final_expression += f'.add(InlineKeyboardButton({variable}, callback_data={variable.lower()}))' return final_expression # output of the function InlineKeyboardMarkup().add(InlineKeyboardButton(VW, callback_data=vw)).add(InlineKeyboardButton(Ford, callback_data=ford)).add(InlineKeyboardButton(Seat, callback_data=seat)).add(InlineKeyboardButton(Nissan, callback_data=nissan)).add(InlineKeyboardButton(KIA, callback_data=kia)).add(InlineKeyboardButton(Skoda, callback_data=skoda)).add(InlineKeyboardButton(Toyota, callback_data=toyota)).add(InlineKeyboardButton(Hyundai, callback_data=hyundai)).add(InlineKeyboardButton(Suzuki, callback_data=suzuki)).add(InlineKeyboardButton(Renault, callback_data=renault)).add(InlineKeyboardButton(Ravon, callback_data=ravon))
解决方案
1. 修正按钮生成逻辑(核心)
不要用字符串拼接生成代码,直接操作InlineKeyboardMarkup实例添加按钮,这是aiogram的标准用法,从根源避免字符串类型问题:
from aiogram.types import InlineKeyboardMarkup, InlineKeyboardButton import psycopg2 # 数据库查询部分优化(处理异常时的变量初始化问题) try: connect = psycopg2.connect(database='car_rental', user='postgres', password='datapass') curs = connect.cursor() curs.execute("""SELECT DISTINCT brand FROM fleet WHERE category = 'economy'""") economy_brands_list = [x[0] for x in curs.fetchall()] except Exception as e: print(f'数据库操作出错: {e}') economy_brands_list = [] # 出错时设为空列表,避免后续报错 finally: # 避免未初始化的变量导致报错 if 'curs' in locals(): curs.close() if 'connect' in locals(): connect.close() # 修正后的按钮生成函数 def economy_bt_generator(): markup = InlineKeyboardMarkup() for brand in economy_brands_list: # 直接传入字符串类型的品牌名和回调数据 button = InlineKeyboardButton(text=brand, callback_data=brand.lower()) markup.add(button) return markup # 使用示例(在命令处理函数中调用) # await message.answer("请选择品牌:", reply_markup=economy_bt_generator())
2. 原代码问题分析
- 原函数通过字符串拼接生成代码是错误逻辑:
variable本身是字符串,但拼接后会变成InlineKeyboardButton(VW, ...),这里的VW会被当作变量而非字符串,导致代码运行时找不到对应变量报错。 - 直接操作
InlineKeyboardMarkup实例,才能正确传递字符串类型的品牌名和回调数据。
内容的提问来源于stack exchange,提问作者Antony_K
相关产品推荐
相关产品推荐

