You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SQLAlchemy操作SQLite时rating字段NOT NULL约束失败求助

问题

我用Python+SQLAlchemy创建了SQLite3的Movie表,定义如下:

class Movie(db.Model):
    id: Mapped[int] = mapped_column(Integer, primary_key=True)
    title: Mapped[str] = mapped_column(String(250), unique=True, nullable=False)
    year: Mapped[int] = mapped_column(Integer, nullable=False)
    description: Mapped[str] = mapped_column(String(250), nullable=False)
    rating: Mapped[float] = mapped_column(Float, nullable=True)
    ranking: Mapped[int] = mapped_column(Integer, nullable=True, autoincrement=True)
    review: Mapped[str] = mapped_column(String(250), nullable=True)
    img_url: Mapped[str] = mapped_column(String(250), nullable=False)

尝试通过接口获取数据,只传入nullable=False的字段来添加新记录,代码如下:

@app.route("/find")
def find_movie():
    movie_api_id = request.args.get("id")
    if movie_api_id:
        movie_api_url = f"{MOVIE_DB_INFO_URL}/{movie_api_id}"
        response = requests.get(movie_api_url, params={"api_key": MOVIES_API_KEYS, "language": "en-US"})
        data = response.json()
        new_movie = Movie(
            title=data["title"],
            year=data["release_date"].split("-")[0],
            img_url=f"https://image.tmdb.org/t/p/w500{data['poster_path']}",
            description=data["overview"]
        )
        db.session.add(new_movie)
        db.session.commit()

        return redirect(url_for("rate_movie", id=new_movie.id))

运行时触发错误:

sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: movie.rating
[SQL: INSERT INTO movie (title, year, description, rating, ranking, review, img_url) VALUES (?, ?, ?, ?, ?, ?, ?)]
[parameters: ('Gladiator', '2000', "In the year 180, the death of emperor Marcus Aurelius throws the Roman Empire into chaos. Maximus is one of the Roman army's most capable and truste ... (168 characters truncated) ... e traders. Renamed Spaniard and forced to become a gladiator, Maximus must battle to the death with other men for the amusement of paying audiences.", None, None, None, 'https://image.tmdb.org/t/p/w500/ty8TGRuvJLPUmAR1H1nRIsgwvim.jpg')]

明明rating字段设置了nullable=True,却触发NOT NULL约束失败,求解决。

解决方法

问题核心是数据库实际表结构与代码中的模型定义不一致。你大概率是修改了模型(将rating设为nullable=True)后,没有同步更新SQLite的表结构——SQLAlchemy默认不会自动修改已存在的表结构,所以数据库里的rating字段仍保留着原来的NOT NULL约束。

具体解决步骤:

  1. 验证表结构:用SQLite可视化工具(比如DB Browser for SQLite)打开数据库文件,查看movie表的rating字段是否真的允许NULL值。如果显示NOT NULL,说明表结构未更新。
  2. 更新表结构:
    • 方案一(开发环境快速处理):直接删除旧数据库文件,重启程序让SQLAlchemy重新生成符合模型定义的表。注意:此操作会丢失所有现有数据,仅适合测试阶段。
    • 方案二(保留数据):使用数据库迁移工具(如Flask项目用Flask-Migrate),执行以下命令:
      flask db migrate -m "make rating nullable"
      flask db upgrade
      
      这会生成迁移脚本并应用到数据库,在保留现有数据的前提下更新表结构。
  3. 额外检查:确认模型定义没有其他冲突(比如是否有代码覆盖了rating的nullable设置),或SQLAlchemy版本是否存在特殊行为(多数版本都遵循nullable参数定义)。

内容的提问来源于stack exchange,提问作者Mbulelo Tshabane

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 05:50:12