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
相关产品推荐
相关产品推荐

