python - 安排 SQLAlchemy 清除表中的所有行
问题描述
我正在尝试创建一个可以安排删除 SQLAlchemy 模型中所有行的函数。
我正在尝试使用apscheduler
来完成这项任务。但我不断收到一条错误消息:
sqlalchemy.orm.exc.UnmappedInstanceError: Class 'flask_sqlalchemy.model.DefaultMeta' is
not mapped; was a class (app.models.User) supplied where an instance was required?
我错过了什么吗?
这是我的app/__init__.py
:
from flask import Flask
from flask_login import LoginManager
from flask_sqlalchemy import SQLAlchemy
from config import Config
app = Flask(__name__)
db = SQLAlchemy()
login = LoginManager()
app.config.from_object(Config)
db.init_app(app)
login.init_app(app)
login.login_view = 'login'
from app import routes, models
这是我的manage.py
:
from apscheduler.schedulers.background import BackgroundScheduler
from app import app, db
from flask_migrate import Migrate
from flask_script import Manager
from app.models import User
manager = Manager(app)
migrate = Migrate(app, db)
def clear_data():
db.session.delete(User)
print("Deleted User table!")
@manager.command
def run():
scheduler = BackgroundScheduler()
scheduler.add_job(clear_data, trigger='interval', seconds=5)
scheduler.start()
app.run(debug=True)
if __name__ == '__main__':
manager.run()
另外,这是我的模型:
from app import db, login
from datetime import datetime
from flask_login import UserMixin
from werkzeug.security import generate_password_hash, check_password_hash
class User(UserMixin, db.Model):
id = db.Column(db.Integer, primary_key=True, unique=True)
api_token = db.Column(db.String(50), unique=True)
username = db.Column(db.String(64), index=True, unique=True)
email = db.Column(db.String(120), index=True, unique=True)
password_hash = db.Column(db.String(128))
todos = db.relationship('Todo', backref='owner', lazy='dynamic')
def __repr__(self):
return '<models.py {}>'.format(self.username)
def set_password(self, password):
self.password_hash = generate_password_hash(password)
def check_password(self, password):
return check_password_hash(self.password_hash, password)
@login.user_loader
def load_user(id):
return User.query.get(int(id))
class Todo(db.Model):
id = db.Column(db.Integer, primary_key=True)
body = db.Column(db.String(140))
timestamp = db.Column(db.DateTime, index=True, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
def __repr__(self):
return '<Todo {}>'.format(self.body)
解决方案
正如您的错误所示,它需要一个对象的实例,而您却将其传递给了一个类。我认为问题出在函数的第一行clear_data
:
db.session.delete(User)
它期望删除用户记录的实例,并且不知道如何仅使用模型来删除整个表。
查看有关如何删除表中所有行的答案。有几种方法可以做到这一点,但这对您来说可能是最小的变化:
db.session.query(User).delete()
在这种情况下,您将添加在SELECT
User 映射到的表中的所有记录,然后删除它们的步骤。
PS:正如链接答案中提到的,你需要.commit()
你的会话,否则它不会粘住,并且会在你关闭连接后回滚。
db.session.commit()
推荐阅读
- python - 运行 keras-text-summarization 时没有名为“keras_text_summarization”的模块
- c++ - 为什么允许这种 C++ 类型推导
- php - 在 php 5.6.23 中设置变量值
- c++ - 将 Boost 属性映射与捆绑类型一起使用
- deployment - 服务器报告 URL 在 Internet Explorer 中不起作用
- sql-server - 在 SQL 中查找和返回模式
- oracle - Oracle 到 csv 导出 - HTML 字符实体
- java - 使用 Mockito 模拟接口时出现异常
- java - JSON 包含具有特定键和值的对象
- swift - 在 Swift 中将嵌套类型的“路径”作为字符串获取