Python python 小脚本 (实现 elasticsearch 导出导入)

肖军 · 2020年07月23日 · 最后由 肖军 回复于 2021年06月02日 · 4402 次阅读

好久没来了,前段时间项目测试需要,需要把现网的 es 数据导出导入测试环境方便测试。就写了一个小脚本。拿出来,说不定以后有童鞋有需要呢。直接上干货了。。。
# 导出脚本

import json
import os
import time
import requests


class exportEsData():
    size = 10000
    def __init__(self, url,index,type):
        self.url = url+"/"+index+"/"+type+"/_search"
        self.urlput=url+"/"+index+"/_settings"
        self.index = index
        self.type = type
    def exportData(self):
        print("export data begin...")
        puthead={"Content-Type": "application/json"}
        param={ "index.max_result_window" :"1000000"}   #修改index max_result_window数据超过100万,一般是根据实际情况,进行修改
        pload=json.dumps(param)
        requests.put(url=self.urlput,data=pload,headers=puthead)
        begin = time.time()
        try:
            os.remove(self.index+"_"+self.type+".json")
        except:
            pass
        msg = requests.get(self.url).text
        print(msg)
        obj = json.loads(msg)
        num = obj["hits"]["total"]
        print(num)
        start = 0
        end =  num/self.size+1
        while(start<end):
            msg =requests.get(self.url+"?from="+str(start*self.size)+"&size="+str(self.size)).text
            self.writeFile(msg)
            start=start+1
        print("export data end!!!\n\t total consuming time:"+str(time.time()-begin)+"s")
    def writeFile(self,msg):
        obj = json.loads(msg)
        vals = obj["hits"]["hits"]
        try:
            f = open(self.index+"_"+self.type+".json","a")
            for val in vals:
                a = json.dumps(val["_source"],ensure_ascii=False)
                f.write(a+"\n")
        finally:
            f.flush()
            f.close()


if __name__ == '__main__':
    exportEsData("http://ip:port","index","type").exportData() #ip,port,index,type根据实际情况替换

# 导入脚本

# coding: utf-8

from elasticsearch import Elasticsearch
import json
import requests
from elasticsearch import helpers

class importEsData():
    def  __init__(self,url,index,type):
        self.url = url
        self.urlputindex=url+"/"+index
        self.urlputmapping=url+"/"+index+"/"+type+"/_mapping"
        self.index = index
        self.type = type
    def importData(self):
        es=Elasticsearch(self.url)
        requests.put(self.urlputindex)  #创建index
        param={mappings}    #这个可以用 http://ip:port/index 获取mappings 来替换mappings内容
        pload=json.dumps(param)
        requests.put(self.urlputmapping,pload)   #创建mappings

        actions=[]  #收集性能数据集合
        f = open(self.index+"_"+self.type+".json",encoding='gbk')

        while 1:
            line=f.readline()
            if not line:
                break
            lined=json.loads(line.encode())
            properties=lined["properties"]   #properties根据实际数据进行替换
            action = {
                    "_index": self.index,
                    "_type": self.type,
                    "_source": {
                        'properties': properties  #properties根据实际数据进行替换
                    }
                }
            actions.append(action)
            if len(actions)==10000:
                helpers.bulk(es, actions)
                del actions[0:len(actions)]
        f.close()
        helpers.bulk(es, actions)

if __name__ == '__main__':
    importEsData("http://ip:port","index","type").importData()  #ip,port,index,type根据实际情况替换
共收到 12 条回复 时间 点赞

这是直接调 es 的查询接口拿数据吗?数据量大的时候会很慢吧?

Jerry li 回复

数据量大的时候是比较慢,百万级别内还是可以用的

能分享自己的效率脚本,我觉得是一个很棒的行为~楼主继续加油,哈哈~(伸手党在窃喜😜

明天试下,刚好我要从生产环境导入数据到测试环境,网上教程都找不到

12楼 已删除

我虽然导出成功了,但控制台报错,能帮我看下吗?
'''
export data begin...

Traceback (most recent call last):
File "E:/AutoTest/学习/json 操作/ES 导出.py", line 51, in
exportEsData("http://192.168.230.135:9200,wuliu,person).exportData(") #ip,port,index,type 根据实际情况替换
File "E:/AutoTest/学习/json 操作/ES 导出.py", line 34, in exportData
self.writeFile(msg)
File "E:/AutoTest/学习/json 操作/ES 导出.py", line 39, in writeFile
vals = obj["hits"]["hits"]
KeyError: 'hits'
'''

回复


你看下,这里是否有两个 hits。
调整一下代码:

肖军 回复

谢谢楼主,导出解决了,非常完美,导入还有点看不懂😅

导入步骤就是在测试环境创建 index,再创建 mapping,再解析已经导出的文件,构造数据,导入到新环境,就是这样,都有注释的,具体哪里不懂?

肖军 回复

导出的文件好像没引用啊,然后 ip,port,index,type 是填测试环境的吗?

肖军 #11 · 2021年06月01日 Author
回复

有引用呀😂
,导入哪里就填哪里的

仅楼主可见
肖军 #13 · 2021年06月02日 Author

mappings 就是 es 存储数据的文档结构,相当于数据库的表结构,关于 mappings 怎么填写获取,我注释里面有写。properties 就是文档内容,这里怎么填写要看你自己的文档内容了,我这里提供了方式方法,但是不包教学。我觉得这些基本的 es 知识多去 baidu,Google 学习一下,那上面的内容比我在这里说的专业详细。

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册