Python操作SQLite:自定义列的数据增删改查方案问询
嘿,这个需求我之前帮人捋过,核心就是动态生成SQL语句+用元数据管理自定义列,既能实现功能,又能摆脱“每次问用户列名”的糟糕体验。我给你一步步拆解,直接上可落地的思路和代码:
第一步:用元数据表管理自定义列
别在内存里瞎维护列名列表了,直接在SQLite里建个专门的表存列信息——这样程序重启也不会丢,还能随时读取所有列的状态。比如:
import sqlite3 def init_db(): conn = sqlite3.connect('user_data.db') cursor = conn.cursor() # 主表:存储用户实际数据 cursor.execute(''' CREATE TABLE IF NOT EXISTS user_records ( id INTEGER PRIMARY KEY AUTOINCREMENT ) ''') # 元数据表:记录所有自定义列的信息 cursor.execute(''' CREATE TABLE IF NOT EXISTS table_columns ( column_name TEXT PRIMARY KEY, column_type TEXT DEFAULT 'TEXT', description TEXT ) ''') # 初始化你说的默认列(name、address这些) default_cols = [ ('name', 'TEXT', '姓名'), ('address', 'TEXT', '地址'), ('date_of_birth', 'TEXT', '出生日期'), ('job', 'TEXT', '职业') ] cursor.executemany(''' INSERT OR IGNORE INTO table_columns (column_name, column_type, description) VALUES (?, ?, ?) ''', default_cols) # 给主表批量加默认列(已存在的列会自动跳过) for col, col_type, _ in default_cols: try: cursor.execute(f'ALTER TABLE user_records ADD COLUMN {col} {col_type}') except sqlite3.OperationalError: pass conn.commit() conn.close()
启动程序先跑一遍init_db(),就能确保所有基础表和默认列都到位。
第二步:新增自定义列的功能
用户要加phone_number列?先把列信息存到元数据表,再给主表加列就行:
def add_custom_column(column_name, column_type='TEXT', description=''): conn = sqlite3.connect('user_data.db') cursor = conn.cursor() # 先检查列是否已存在 cursor.execute('SELECT column_name FROM table_columns WHERE column_name = ?', (column_name,)) if cursor.fetchone(): print(f"列「{column_name}」已经存在啦!") conn.close() return # 把新列信息存入元数据表 cursor.execute(''' INSERT INTO table_columns (column_name, column_type, description) VALUES (?, ?, ?) ''', (column_name, column_type, description)) # 给主表新增列 try: cursor.execute(f'ALTER TABLE user_records ADD COLUMN {column_name} {column_type}') print(f"成功新增列:{column_name}") except sqlite3.OperationalError as e: print(f"新增列失败:{e}") conn.rollback() conn.commit() conn.close() # 调用示例:用户新增电话号码列 add_custom_column('phone_number', 'TEXT', '电话号码')
第三步:动态插入数据(不用问列名)
直接从元数据表拉取所有列,让用户逐个输入对应值就行,不用记列名:
def insert_user_record(): conn = sqlite3.connect('user_data.db') cursor = conn.cursor() # 获取所有列名(排除自增的id) cursor.execute('SELECT column_name FROM table_columns ORDER BY column_name') columns = [row[0] for row in cursor.fetchall()] # 收集用户输入 record_data = {} print("\n请输入用户信息:") for col in columns: value = input(f"{col}:") record_data[col] = value # 动态生成INSERT语句 col_str = ', '.join(columns) placeholder_str = ', '.join(['?' for _ in columns]) sql = f'INSERT INTO user_records ({col_str}) VALUES ({placeholder_str})' # 执行插入 try: cursor.execute(sql, tuple(record_data.values())) print("数据插入成功!") except sqlite3.Error as e: print(f"插入失败:{e}") conn.commit() conn.close()
用户输入时,程序会自动列出所有列(包括新增的phone_number),直接填值就行,完全不用手动输列名。
第四步:动态查询数据(用序号选列,避免拼写错误)
让用户用序号选要查的列,比输入列名友好10倍:
def query_user_records(): conn = sqlite3.connect('user_data.db') cursor = conn.cursor() # 获取所有列的名称和描述 cursor.execute('SELECT column_name, description FROM table_columns ORDER BY column_name') columns = cursor.fetchall() # 显示列选项 print("\n可选查询列:") for idx, (col, desc) in enumerate(columns, 1): print(f"{idx}. {col}({desc})") print("0. 查询所有列") choice = input("请选择列序号:") # 处理用户选择 if choice == '0': selected_cols = [col for col, _ in columns] else: try: idx = int(choice) - 1 selected_cols = [columns[idx][0]] except (IndexError, ValueError): print("选择无效,默认查询所有列") selected_cols = [col for col, _ in columns] # 动态生成SELECT语句 col_str = ', '.join(selected_cols) sql = f'SELECT id, {col_str} FROM user_records' cursor.execute(sql) # 打印结果 print("\n查询结果:") print(f"ID\t" + '\t'.join(selected_cols)) print("-" * 60) for row in cursor.fetchall(): print('\t'.join(map(str, row))) conn.close()
第五步:编辑/删除操作(同样用序号选列/记录)
编辑操作示例:让用户选记录ID和要修改的列,再输入新值,完全不用记列名:
def update_user_record(): conn = sqlite3.connect('user_data.db') cursor = conn.cursor() # 获取所有列和记录ID cursor.execute('SELECT column_name, description FROM table_columns ORDER BY column_name') columns = cursor.fetchall() cursor.execute('SELECT id FROM user_records') record_ids = [str(row[0]) for row in cursor.fetchall()] if not record_ids: print("没有可修改的用户记录!") conn.close() return # 选要修改的记录ID record_id = input(f"\n请输入要修改的记录ID(可选:{', '.join(record_ids)}):") if record_id not in record_ids: print("无效的记录ID!") conn.close() return # 选要修改的列 print("\n可选修改列:") for idx, (col, desc) in enumerate(columns, 1): print(f"{idx}. {col}({desc})") choice = input("请选择列序号:") try: idx = int(choice) - 1 selected_col = columns[idx][0] except (IndexError, ValueError): print("选择无效!") conn.close() return # 输入新值并执行修改 new_value = input(f"\n请输入{selected_col}的新值:") sql = f'UPDATE user_records SET {selected_col} = ? WHERE id = ?' try: cursor.execute(sql, (new_value, record_id)) print("修改成功!") except sqlite3.Error as e: print(f"修改失败:{e}") conn.commit() conn.close()
删除操作思路类似,让用户输入要删除的记录ID即可,或者结合列条件动态生成DELETE语句。
最后提个用户体验小技巧
做个简单的控制台菜单,让用户不用记命令:
===== 用户数据管理系统 ===== 1. 新增自定义列 2. 插入用户数据 3. 查询用户数据 4. 修改用户数据 5. 删除用户数据 6. 退出 请选择操作序号:
这样用户操作起来更直观,完全不用纠结列名怎么输。
内容的提问来源于stack exchange,提问作者Jo Sky
相关产品推荐
相关产品推荐

