Flask-SQLAlchemy的unique关键字在SQLite数据库中未生效问题咨询
解决Flask-SQLAlchemy + SQLite中username唯一约束不生效的问题
嘿,我之前也踩过类似的坑,给你列几个实用的排查方向,应该能搞定这个问题:
一定要在Flask应用上下文里执行
db.create_all()
从Flask 2.0版本开始,直接在脚本顶层调用db.create_all()经常会因为缺失应用上下文,导致SQLAlchemy无法正确生成表的约束规则。你可以把代码改成这样试试:app = Flask(__name__) app.config["SQLALCHEMY_DATABASE_URI"] = "sqlite:///database.db" db = SQLAlchemy(app) class UserModel(db.Model): __tablename__ = "users" id = db.Column(db.Integer, primary_key=True) email = db.Column(db.String, nullable=False) username = db.Column(db.String, nullable=False, unique=True) password = db.Column(db.String, nullable=False) public_id = db.Column(db.String, nullable=False, default=str(uuid.uuid4()).replace("-", "")) # 用上下文包裹表创建操作 with app.app_context(): db.create_all()直接去SQLite里检查表结构,确认约束真的生效了
有时候代码写对了,但实际生成的表没带上约束。你可以打开终端,执行sqlite3 database.db进入数据库交互模式,然后敲PRAGMA table_info(users);,看输出里username那一行的unique列是不是1——要是0的话,说明create_all()根本没生成约束,那就要回头重点排查上下文或配置问题。如果需要大小写不敏感的唯一验证
要是你发现插入"John"和"john"能同时存在,这不是约束没生效,是SQLite默认大小写敏感。可以给字段加个排序规则,让它忽略大小写:username = db.Column(db.String, nullable=False, unique=True, collation='NOCASE')确认没有其他代码干扰表创建
比如有没有用Flask-Migrate之类的迁移工具?如果之前生成过迁移脚本,可能会覆盖create_all()生成的表结构;或者有没有其他地方重新定义了UserModel?不过你说每次都建全新数据库,这个概率比较低,但还是可以快速排查下。
内容的提问来源于stack exchange,提问作者Anthony Ma
相关产品推荐
相关产品推荐

