前言
- MongoDB 在数据库层面不能像 MySQL 一样设置自动创建 create_time/update_time,自动更新 update_time
- 可以自己封装函数在应用程序中实现类似效果
- 推荐学习唐建法《MongoDB 高手课》
本文测试环境
# 服务端 Ubuntu 18.04 LTS MongoDB 4.2.5 # 客户端 Windows 10 Python 3.8.2 pymongo 3.10.1
实例
# 类似 MySQL 以下语句,并更新时间
INSERT INTO ... ON DUPLICATE KEY UPDATE ...
# 第一次执行时,生成 create_time 和 update_time
# 第二次执行时,更新 update_time
Mongo Shell
方式一
db.student.updateOne( { sno: 1 }, { $setOnInsert: { create_time: new Date() }, $set: { sname: "qbit", update_time: new Date() } }, { upsert: true } )
方式二(currentDate)
/* 约等于上面的语句。 通常下面的语句在新建 document 时, update_time 会比 create_time 晚一点。 因为 new Date() 是 js 函数,在客户端生成; currentDate 获取的是服务器时间 */ db.student.updateOne( { sno: 1 }, { $currentDate: { update_time: true }, $setOnInsert: { create_time: new Date() }, $set: { sname: "qbit" } }, { upsert: true } )
pymongo(reading-time)
Python 代码
#encoding: utf-8 #author: qbit #date: 2020-04-24 #summary: 封装 pymongo 函数,自动更新时间 import time from datetime import datetime, timedelta, timezone from pprint import pprint import pytz import pymongo from bson.codec_options import CodecOptions
def upsert_autotime(coll: pymongo.collection.Collection, filterDict: dict, updateDict: dict): r""" coll: MongoDB 集合 filterDict: 过滤条件,须是主键 updateDict: 更新字段内容 """ # 0 区 dt0 = datetime.utcnow() updateDict['update_time'] = dt0 updateDict = {'$set': updateDict} updateDict['$setOnInsert'] = { 'create_time': dt0 } return coll.update_one(filterDict, updateDict, upsert=True)
if __name__ == "__main__": username = 'qbit' password = 'xxx' host = '192.168.0.72' port = 27017 dbname = 'student' connStr = f'mongodb://{username}:{password}@{host}:{port}/{dbname}?authSource=admin' # 设置读取来时间的时区 options = CodecOptions(tz_aware=True, tzinfo=pytz.timezone('Asia/Shanghai')) db = pymongo.MongoClient(connStr).get_database(codec_options=options) coll = db.student coll.drop() filterDict = {"sno": 1} updateDict = {"sname": "qbit"} print('///////////////// 111 ///////////////////') upsert_autotime(coll, filterDict, updateDict) # 第 1 次执行 document = coll.find_one() document['create_time'] = document['create_time'].strftime('%Y-%m-%d %H:%M:%S') document['update_time'] = document['update_time'].strftime('%Y-%m-%d %H:%M:%S') pprint(document) print('///////////////// 222 ///////////////////') time.sleep(2) # 休眠 2s upsert_autotime(coll, filterDict, updateDict) # 第 2 次执行 document = coll.find_one() document['create_time'] = document['create_time'].strftime('%Y-%m-%d %H:%M:%S') document['update_time'] = document['update_time'].strftime('%Y-%m-%d %H:%M:%S') pprint(document)
运行结果
///////////////// 111 /////////////////// {'_id': ObjectId('5ea2acd4bb3447a6a5fe18fc'), 'create_time': '2020-04-24 09:09:39', 'sname': 'qbit', 'sno': 1, 'update_time': '2020-04-24 09:09:39'} ///////////////// 222 /////////////////// {'_id': ObjectId('5ea2acd4bb3447a6a5fe18fc'), 'create_time': '2020-04-24 09:09:39', 'sname': 'qbit', 'sno': 1, 'update_time': '2020-04-24 09:09:41'}
本文出自 qbit snap
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。