PostgreSQL操作报错:KeyError密码生成问题排查与修复方案
问题原因与修复方案
核心原因
你遇到的KeyError: 'ascii_lettersdigitspunctuation'和数据库编码无关,完全是Python代码的写法错误:你把string模块的三个独立属性名ascii_letters、digits、punctuation错误拼接成了一个不存在的键名,试图用字典访问的方式获取这个不存在的属性,才触发了KeyError。
排查步骤
- 找到代码中生成密码字符集的代码段,检查是否存在类似错误写法:
import string # 错误写法:将三个属性名连写,当成字典键访问 chars = string['ascii_lettersdigitspunctuation'] - 确认
string模块的合法属性:string.ascii_letters对应大小写字母,string.digits对应数字,string.punctuation对应标点符号,三者是独立属性,不存在合并后的属性名。
修复后的完整代码示例
1. 先安装依赖库
pip install psycopg2-binary cryptography
2. 修正后的功能代码
import string import random import psycopg2 from cryptography.fernet import Fernet # 生成加密密钥(首次运行后建议保存密钥到安全位置,避免每次生成新密钥导致旧密码无法解密) key = Fernet.generate_key() cipher = Fernet(key) # 生成强密码函数 def generate_strong_password(length=16): # 正确拼接字符集:分别调用三个属性再合并 char_pool = string.ascii_letters + string.digits + string.punctuation # 确保密码包含四类字符(大写、小写、数字、标点) password_components = [ random.choice(string.ascii_uppercase), random.choice(string.ascii_lowercase), random.choice(string.digits), random.choice(string.punctuation) ] # 填充剩余长度的随机字符 password_components += [random.choice(char_pool) for _ in range(length - 4)] # 打乱字符顺序 random.shuffle(password_components) return ''.join(password_components) # 加密并写入PostgreSQL函数 def save_encrypted_password(username, encrypted_pwd): conn = None try: # 替换为你的数据库连接参数 conn = psycopg2.connect( dbname="your_db_name", user="your_db_user", password="your_db_pwd", host="localhost", port="5432" ) cur = conn.cursor() # 创建存储表(如果不存在) cur.execute(""" CREATE TABLE IF NOT EXISTS secure_passwords ( id SERIAL PRIMARY KEY, username VARCHAR(60) UNIQUE NOT NULL, encrypted_password TEXT NOT NULL ) """) # 插入或更新密码 cur.execute(""" INSERT INTO secure_passwords (username, encrypted_password) VALUES (%s, %s) ON CONFLICT (username) DO UPDATE SET encrypted_password = EXCLUDED.encrypted_password """, (username, encrypted_pwd.decode('utf-8'))) conn.commit() cur.close() except Exception as e: print(f"数据库操作失败: {str(e)}") finally: if conn: conn.close() # 主执行逻辑 if __name__ == "__main__": target_username = "demo_user" raw_pwd = generate_strong_password() print(f"生成的原始密码: {raw_pwd}") # 加密密码 encrypted_pwd = cipher.encrypt(raw_pwd.encode('utf-8')) # 写入数据库 save_encrypted_password(target_username, encrypted_pwd) print("密码已加密并成功写入数据库")
关键修复说明
- 把错误的
string['ascii_lettersdigitspunctuation']替换为string.ascii_letters + string.digits + string.punctuation,正确构建密码字符池。 - 优化密码生成逻辑,确保生成的密码符合强密码标准(包含四类字符)。
- 使用
cryptography库的Fernet进行对称加密,保证密码存储的安全性。
内容的提问来源于stack exchange,提问作者Lesh 1337
相关产品推荐
相关产品推荐

