我使用Flask,Flask-Restful和Flask-sqlAlchemy制作了一个简单的rest api,其中有一个用户资源和一个item资源。用户资源是项资源的父资源。
那是
获取https://example.com/users/1/items 获取所有物品资源
我想在每个月后自动删除所有项目。问题是如何跟踪月末?
我做了一些研究,发现了python datetime和日历库。
下面的代码是如何获取用户注册的某月的月末,然后可以计算该年月份的其余开始日期和结束日期并将其保存在数据库中。但是现在我将不得不每次检查datetime.datetime.today(),然后检查开始和结束日期,并删除特定用户下的项目资源。每次检查datetime.datetime.today()是否有效,如果等于结束日期,则删除所有项目资源?
这是我计算开始日期和结束日期的方式
import datetime
import calendar
today = datetime.datetime.today()
days_in_current_month = calendar.monthrange(today.year, today.month)[1]
days_till_this_month_end = days_in_current_month -today.day
start_date = today + datetime.timedelta(days = days_till_this_month_end +1)
end_date = start_date
while some_condition:
# details of the condision
days_in_current_month = calendar.monthrange(end_date.year, end_date.month)[1]
end_date = end_date + datetime.timedelta(days = days_till_this_month_end +1)
这是我的UserModel:
class UserModel(db.Model):
__tablename__ = "users"
id = db.Column(db.Integer, primary_key = True)
firstname = db.Column(db.String(80))
lastname = db.Column(db.String(80))
email = db.Column(db.String(255))
password = db.Column(db.String())
items = db.relationship('ItemModel', lazy = "dynamic")
这是我的ItemModel:
class ItemModel(db.Model):
__tablename__ = "categories"
id = db.Column(db.Integer, primary_key = True)
name = db.Column(db.String(255))
date = db.Column(db.DateTime, default=datetime.utcnow)
user_id = db.Column(db.Integer, db.ForeignKey('users.id'))
user = db.relationship('UserModel')
最后删除项目,我可以执行以下操作:
@staticmethod
def delete_from_db():
ItemModel.query.filter(start_date <= end_date).delete()
db.session.commit()
答案 0 :(得分:2)
您的#include "lib.h"
namespace cs{
class A
{
protected:
int x;
float y;
friend int myFunc(void* userdata, int valInt, float valFloat);
public:
void abc()
{
libFunc(this, myFunc);
}
};
myFunc(void *userdata, int x, float y){
// I would like this function to be inaccessible from the client
A *obj = (A*) userdata;
obj->x = x;
obj->y = y;
}
}
查询过滤器未指定任何列; ItemModel
表达式始终为start_date <= end_date
(因为True
的值总是会比您的end_date
的时间晚)。您也使事情复杂化了。
您要做的就是删除当前月初 的所有行。数据库将从那里获取数据。可以通过以下方式轻松确定当前月份的开始时间:
start_date
在每个查询上运行此命令的成本很便宜,尤其是在为import datetime
today = datetime.date.today()
month_start = today.replace(day=1) # set day of the month to 1
ItemModel.query.filter(ItemModel.date < month_start).delete()
列建立索引的情况下。
如果要针对特定的数据库,则也可以使用数据库的日期函数。例如,PostgreSQL有一个方便的date_trunc()
function,可用于指定要删除的行:
ItemModel.date
这将使用PostgreSQL CURRENT_DATE
value,将其截断为当前月份(将日期设置为1),然后删除当前月份之前的所有行。
如果您认为这些删除查询的成本太高而无法在每个请求上运行,请考虑在ItemModel.query.filter(
ItemModel.date < func.date_trunc('month', func.current_date())
).delete()
表中创建一个table view,并在您的SQLAlchemy模型中使用该视图。然后,视图查询仅显示当前月份的项目:
items
并使用CREATE OR REPLACE current_items WITH
SELECT * FROM items
WHERE items.date >= date_trunc(CURRENT_DATE, 'month')
作为表名来备份current_items
对象,并进行单独的批处理,从item表中删除任何较旧的行,以保持数据库的干净。这样,您的SQLAlchemy查询就只能查看当月的项目,并且在批处理过程将删除这些行时,删除一次完成。
您也可以让SQLAlchemy通过事件挂钩自动应用过滤器,而不是使用视图。这是filtered query implementation:
ItemModel