起因: 从ES集群A往ES集群B导数,然后比对2个ES的数据差异,逐个ID比对。由于ES集群A的版本是1.4.x,ES集群B的版本是5.3.x,所以无法使用同一个ES client包

1. 加载不同版本的client包

对比的过程是,取相同发布时间区间的文章ID,然后比对id的差异
伪码如下:

es_A_ids = get_es_A_ids()
es_B_ids = get_es_B_ids()
diff_ids = es_A_ids - es_B_ids

可以想到的是在访问完集群A后重新加载elasticsearch 库

## load elasticsearch==1.4.0
es_A_ids = get_es_A_ids()
## load elasticsearch==5.3.0
es_B_ids = get_es_B_ids()
diff_ids = es_A_ids - es_B_ids

但是很有趣的是,elasticsearch在load完上一个版本以后,它的版本没有发生变化

2. 清理已经load 的module

经过查资料,我明确了这个问题,python的module,只会被load,有且一次,所以要保证不同版本的module被再次load,只能先clear 原先load的module
ES的module都以elasticsearch开头,因此把它们都清理掉

for key in sys.modules.keys():
    if key.startswith('elasticsearch'):
        del sys.modules[key]

完整代码

import importlib
import sys
# use elasticsearch 5.x
es_lib_path = "/Users/woshiaotian/es_5x/lib/python2.7/site-packages"
# 注意要把es_lib_path放在sys.path 的首位,确保load module的时候,该目录下的ES库,能够被优先加载
sys.path.insert(0, es_lib_path)  
#print sys.path
elasticsearch = importlib.import_module("elasticsearch")
print elasticsearch
sys.path.pop(0)

for key in sys.modules.keys():
    if key.startswith('elasticsearch'):
        print  key
        del sys.modules[key]

# use elasticsearch 1.x
es_lib_path = "/Users/woshiaotian/es_1x/lib/python2.7/site-packages"
sys.path.insert(0, es_lib_path)
elasticsearch = importlib.import_module("elasticsearch")
print elasticsearch
sys.path.pop(0)
#print sys.path

for key in sys.modules.keys():
    if key.startswith('elasticsearch'):
        print  key
        del sys.modules[key]

sys.modules
This is a dictionary that maps module names to modules which have already been loaded. This can be manipulated to force reloading of modules and other tricks. However, replacing the dictionary will not necessarily work as expected and deleting essential items from the dictionary may cause Python to fail.

参考资料

  1. https://docs.python.org/3/library/sys.html

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据