在Flask-SQLAlchemy中用datetime.utcnow()设默认值报错
解决Flask-SQLAlchemy中AttributeError: 'SQLAlchemy'对象没有'Datetime'属性的问题
嘿,这个问题我太熟悉了!你遇到的错误其实是个超容易犯的小疏忽——类型名称的大小写搞错了!SQLAlchemy里的日期时间类型是DateTime(大写的T),但你写成了Datetime,这才导致了“找不到属性”的报错。
我给你整理了修正后的完整代码,顺便把默认值的正确用法也理清楚:
from flask import Flask, flash, render_template, redirect, request, url_for from flask_sqlalchemy import SQLAlchemy from datetime import datetime app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///HRS.sqlite3' app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False # 加这个能关掉不必要的追踪警告,建议加上 app.config['SECRET_KEY'] = 'any key' db = SQLAlchemy(app) # 假设你的模型是Task(你之前写的Tre...应该是截断了) class Task(db.Model): id = db.Column(db.Integer, primary_key=True) # 这里注意是db.DateTime,不是db.Datetime! # 另外默认值用datetime.utcnow(不要加括号!),这样每次创建实例才会生成当前时间 created_at = db.Column(db.DateTime, default=datetime.utcnow) # 其他字段按需添加... # 首次请求前创建数据库表 @app.before_first_request def init_db(): db.create_all() if __name__ == '__main__': app.run(debug=True)
这里还要提醒你一个关键细节:设置默认值的时候,一定要用datetime.utcnow而不是datetime.utcnow()。原因很简单:
- 如果加了括号,这个函数会在你定义模型的时候就立刻执行一次,所有后续创建的实例都会用这个固定的时间;
- 不加括号的话,SQLAlchemy会在每次创建新记录的时候调用这个函数,生成实时的UTC时间,这才是你想要的默认值效果。
最后,加上SQLALCHEMY_TRACK_MODIFICATIONS = False是个好习惯,能避免Flask-SQLAlchemy抛出不必要的性能警告。
内容的提问来源于stack exchange,提问作者Stephen C. O.




