Python中如何实现服务器后端只保存一天的最后一条信息

数据是保存到 mongodb,希望保存某条数据时,只保存一天最后一条。我想到的是,保存每条数据之前,按创建时间的字段,查询所有记录并删除。不知道有没有更好的做法
Python中如何实现服务器后端只保存一天的最后一条信息

13 回复

日期为主键然后 insert ?


这个需求很常见,比如日志聚合、状态快照或者每日数据汇总。核心思路是结合日期判断和覆盖写入。

最直接的方法是用日期作为标识。每次收到新数据时,检查存储里是否已有当天的记录,有就更新,没有就新建。这里给个用字典模拟内存存储的例子,实际应用你可能用数据库:

import datetime
from typing import Dict, Any

class DailyLatestStore:
    def __init__(self):
        # 用字典模拟存储,key是日期字符串,value是数据
        self._storage: Dict[str, Any] = {}
    
    def save_data(self, data: Any) -> None:
        """保存数据,每天只保留最后一条"""
        today = datetime.date.today().isoformat()  # 获取当前日期,如'2023-10-27'
        self._storage[today] = data  # 直接覆盖当天数据
    
    def get_today_data(self) -> Any:
        """获取今天保存的数据"""
        today = datetime.date.today().isoformat()
        return self._storage.get(today)
    
    def cleanup_old_data(self, days_to_keep: int = 1) -> None:
        """清理旧数据,只保留最近N天的数据"""
        cutoff_date = datetime.date.today() - datetime.timedelta(days=days_to_keep)
        dates_to_remove = []
        
        for date_str in self._storage:
            record_date = datetime.date.fromisoformat(date_str)
            if record_date < cutoff_date:
                dates_to_remove.append(date_str)
        
        for date_str in dates_to_remove:
            del self._storage[date_str]

# 使用示例
store = DailyLatestStore()

# 模拟一天内多次保存
store.save_data({"temperature": 25, "humidity": 60})
store.save_data({"temperature": 26, "humidity": 62})  # 覆盖前一条
store.save_data({"temperature": 24, "humidity": 65})  # 再次覆盖

# 获取今天的数据
print(store.get_today_data())  # 输出: {'temperature': 24, 'humidity': 65}

# 清理旧数据(比如只保留最近1天)
store.cleanup_old_data(days_to_keep=1)

如果你用数据库(比如SQLite或PostgreSQL),可以在数据库层面实现。比如建表时把日期作为唯一索引或主键的一部分,用ON CONFLICT REPLACEUPSERT操作:

import sqlite3
import datetime

def setup_database():
    conn = sqlite3.connect('daily_data.db')
    cursor = conn.cursor()
    cursor.execute('''
        CREATE TABLE IF NOT EXISTS daily_records (
            date TEXT PRIMARY KEY,
            data TEXT,
            updated_at TIMESTAMP
        )
    ''')
    conn.commit()
    return conn

def save_daily_data(conn, data: str):
    today = datetime.date.today().isoformat()
    cursor = conn.cursor()
    
    # 使用UPSERT语法(SQLite 3.24+)
    cursor.execute('''
        INSERT INTO daily_records (date, data, updated_at)
        VALUES (?, ?, CURRENT_TIMESTAMP)
        ON CONFLICT(date) DO UPDATE SET
            data = excluded.data,
            updated_at = CURRENT_TIMESTAMP
    ''', (today, data))
    
    conn.commit()

# 使用
conn = setup_database()
save_daily_data(conn, '{"temp": 24}')

关键就两点:用日期做唯一标识,写入时执行覆盖更新。

总结:用日期做key进行覆盖写入。

把数据库的主键设计成日期,比如:2018 年 09 月 25 日,如果发现有记录就更新,没有就新增。

可以再优化一下主键,时间戳的精度是秒,如果把时间戳除一天的秒数( 86400 ),也相当于是当天的日期。

实际保存了不同用户的不同项目的不同信息,如果日期设为主键,是不是数据库只存一个人的了?

那你用 DateTIme+UserName 做主键不就行了

但是我存了不同用户的信息,日期做主键那只能存一个人的了

傻了,是呀,谢谢 ; )

upsert {date: “2018-09-25”}, {value: “text text”}

别物理删除,改下记录状态就好,其他随便你怎么弄

MongoDB 不知道怎么弄,但是 mysql 可以把 uid+date 设置为唯一索引,然后 insert…on duplicate key update

也可行诶

嗯,正准备用这个方案

回到顶部