我有多个Python脚本使用pyMongo写入Mongodb。另一个Python脚本如何观察Mongo查询的更改并在发生更改时执行某些功能?设置了启用oplog的mongodb。
答案 0 :(得分:7)
前段时间我用Python编写了MongoDB的增量备份工具。该工具通过拖尾oplog
来监控数据更改。这是代码的相关部分。
更新了答案,pymongo 3
from time import sleep
from pymongo import MongoClient, ASCENDING
from pymongo.cursor import CursorType
from pymongo.errors import AutoReconnect
# Time to wait for data or connection.
_SLEEP = 1.0
if __name__ == '__main__':
oplog = MongoClient().local.oplog.rs
stamp = oplog.find().sort('$natural', ASCENDING).limit(-1).next()['ts']
while True:
kw = {}
kw['filter'] = {'ts': {'$gt': stamp}}
kw['cursor_type'] = CursorType.TAILABLE_AWAIT
kw['oplog_replay'] = True
cursor = oplog.find(**kw)
try:
while cursor.alive:
for doc in cursor:
stamp = doc['ts']
print(doc) # Do something with doc.
sleep(_SLEEP)
except AutoReconnect:
sleep(_SLEEP)
另见http://api.mongodb.com/python/current/examples/tailable.html。
原始回答,pymongo 2
from time import sleep
from pymongo import MongoClient
from pymongo.cursor import _QUERY_OPTIONS
from pymongo.errors import AutoReconnect
from bson.timestamp import Timestamp
# Tailable cursor options.
_TAIL_OPTS = {'tailable': True, 'await_data': True}
# Time to wait for data or connection.
_SLEEP = 10
if __name__ == '__main__':
db = MongoClient().local
while True:
query = {'ts': {'$gt': Timestamp(some_timestamp, 0)}} # Replace with your query.
cursor = db.oplog.rs.find(query, **_TAIL_OPTS)
cursor.add_option(_QUERY_OPTIONS['oplog_replay'])
try:
while cursor.alive:
try:
doc = next(cursor)
# Do something with doc.
except (AutoReconnect, StopIteration):
sleep(_SLEEP)
finally:
cursor.close()
答案 1 :(得分:3)
我今天遇到了这个问题,并没有在任何地方找到更新的答案。
Cursor类自v3.0起已更改,不再接受tailable
和await_data
参数。此示例将在发现记录 newer 而不是找到的最后一个记录时挂起oplog并打印oplog记录。
# Adapted from the example here: https://jira.mongodb.org/browse/PYTHON-735
# to work with pymongo 3.0
import pymongo
from pymongo.cursor import CursorType
c = pymongo.MongoClient()
# Uncomment this for master/slave.
oplog = c.local.oplog['$main']
# Uncomment this for replica sets.
#oplog = c.local.oplog.rs
first = next(oplog.find().sort('$natural', pymongo.DESCENDING).limit(-1))
ts = first['ts']
while True:
cursor = oplog.find({'ts': {'$gt': ts}}, cursor_type=CursorType.TAILABLE_AWAIT, oplog_replay=True)
while cursor.alive:
for doc in cursor:
ts = doc['ts']
print doc
# Work with doc here
答案 2 :(得分:1)
使用tailable cursor查询oplog。
实际上很有趣,因为oplog监控正是最初添加tailable-cursor功能的原因。我发现它对其他东西也非常有用(例如,实现基于mongodb的pubsub,例如参见this post),但这是最初的目的。
答案 3 :(得分:0)
我有同样的问题。我把这个rescommunes/oplog.py放在一起。查看评论并查看__main__
,了解如何在脚本中使用它。