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

Ubuntu下Python REST-API开发:SQLAlchemy操作SQLite报错排查

解决SQLAlchemy中add_book方法的TypeError问题

问题根源分析

你遇到的TypeError主要来自两个核心问题:

  • add_book是类级别的操作,但你没有用@classmethod装饰器标记,导致调用时无法正确绑定到Book类的上下文。
  • 错误使用了db.Session(大写S),SQLAlchemy中实际应该用db.session(小写s)来获取当前会话实例。

另外你的代码还有几个潜在小问题,我一起帮你修正。

逐步修复代码

1. 修正add_book方法

给add_book添加@classmethod装饰器,并把db.Session改为db.session:

@classmethod
def add_book(cls, _name, _price, _isbn):
    new_book = Book(name=_name, price=_price, isbn=_isbn)
    db.session.add(new_book)
    db.session.commit()

2. 修正get_all_books方法

这个方法是获取所有书籍,不需要实例化Book,所以同样要改为类方法:

@classmethod
def get_all_books(cls):
    return cls.query.all()

3. 修正__repr__方法的JSON处理

json.dump()是用来把JSON写入文件对象的,这里应该用json.dumps()返回字符串:

def __repr__(self):
    book_object = {'name': self.name, 'price': self.price, 'isbn': self.isbn}
    return json.dumps(book_object)

完整修复后的BookModel.py

from flask import Flask
from flask_sqlalchemy import SQLAlchemy
import json
from settings import app

db = SQLAlchemy(app)

class Book(db.Model):
    __tablename__ = 'books'
    id = db.Column(db.Integer, primary_key=True)
    name = db.Column(db.String(80), nullable=False)
    price = db.Column(db.Float, nullable=False)
    isbn = db.Column(db.Integer)

    @classmethod
    def add_book(cls, _name, _price, _isbn):
        new_book = cls(name=_name, price=_price, isbn=_isbn)
        db.session.add(new_book)
        db.session.commit()

    @classmethod
    def get_all_books(cls):
        return cls.query.all()

    def __repr__(self):
        book_object = {'name': self.name, 'price': self.price, 'isbn': self.isbn}
        return json.dumps(book_object)

测试修复后的代码

现在重新进入Python交互环境测试:

>>> from BookModel import *
>>> Book.add_book("ss", 55.6, 556)
>>> books = Book.get_all_books()
>>> print(books)
[{"name": "ss", "price": 55.6, "isbn": 556}]

额外优化建议

  • 可以给Book类添加一个to_dict方法,更优雅地返回字典格式的数据,代替在__repr__里处理JSON:
    def to_dict(self):
        return {
            'id': self.id,
            'name': self.name,
            'price': self.price,
            'isbn': self.isbn
        }
    
    然后__repr__可以简化为:return str(self.to_dict())
  • 建议添加错误捕获,比如在add_book中处理可能的数据库提交异常:
    @classmethod
    def add_book(cls, _name, _price, _isbn):
        try:
            new_book = cls(name=_name, price=_price, isbn=_isbn)
            db.session.add(new_book)
            db.session.commit()
            return new_book
        except Exception as e:
            db.session.rollback()
            raise e
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.11 09:07:09