最近在工程上遇到MongoDB表增量复制到另一个表的问题。需求是因为原表的数据会定时删除,而目前想要保存原表的数据。简单理解为:原表删,新表不删。原表增,新表增。
使用MongoShell很容易解决:
将一个实例的表复制到另一个实例的表(同一个数据库)
db.collection_name.find().forEach(function(d){db.getSiblingDB('new_database')['collection_name'].insert(d);})
collection_name:数据库表名
new_database:目标数据库
而使用pymongo时通过update实现:
mongodb文档
关键在于upsert参数设置:为True时,如果没有匹配的文档,则创建一个新文档
核心代码:
for doc in orgin_collections["cursor"]["firstBatch"]:
#将原表数据增量复制到备份表
mongo_db.command('update', update=MONGO_COPY_TABLE, updates=[{"q": doc, "u": doc, "upsert": True}],
bypassDocumentValidation=True)
全部代码:
import pymongo
import time
import datetime
"""
配置参数
"""
MONGO_IP = '192.168.1.103'
MONGO_PORT = 27017
#刷新同步时间 秒
SHUFFLE_TIME = 60
#数据库名
MONGO_DATABASE = 'things'
#原始表名
MONGO_ORIGIN_TABLE = 'things_journal'
#备份表名
MONGO_COPY_TABLE = 'cauc_test'
#历史数据,为了判断是否要同步
OLD_DATA = ''
"""
连接到数据库
"""
mongo_client = pymongo.MongoClient(MONGO_IP, MONGO_PORT)
mongo_db = mongo_client[MONGO_DATABASE]
"""
复制表数据函数
"""
def copyNewTable():
#获取原表数据
global OLD_DATA
orgin_collections = mongo_db.command('find', find=MONGO_ORIGIN_TABLE, skip=0)
if OLD_DATA == orgin_collections:
#原表无更新
print("[{}] {}没有变化,暂不同步".format(datetime.datetime.now(), MONGO_ORIGIN_TABLE))
else:
#原表有更新
OLD_DATA = orgin_collections
for doc in orgin_collections["cursor"]["firstBatch"]:
#将原表数据增量复制到备份表
mongo_db.command('update', update=MONGO_COPY_TABLE, updates=[{"q": doc, "u": doc, "upsert": True}],
bypassDocumentValidation=True)
print("[{}] {}已同步到{}".format(datetime.datetime.now(),MONGO_ORIGIN_TABLE,MONGO_COPY_TABLE))
if __name__ == '__main__':
while(1):
copyNewTable()
time.sleep(SHUFFLE_TIME)
输出结果: