用Python脚本迁移MongoDB数据到金仓-kingbase数据库
1、首先需要明确MongoDB与kingbase的对应关系,collection相当于table,filed相当于字段,根据这个对应关系创建表;
此次迁移的MongoDB里的数据字段是:_id(自动生成的objectid),image(转成二进制存储的文档)
所以在金仓里创建表 create table admin(id varchar,image bytea);
2、安装Python环境,由于是内网环境,没有yum源,需要从能连接互联网的环境下载好相应的安装包
Python:3.9.0版本
用到以下这些包
import pymongo
import ksycopg2
import concurrent.futures
from ksycopg2 import pool
import logging
from urllib.parse import quote_plus
------------------------------------------------------------------------------------
pip download pymongo -d pymongo_packages --下载pymongo库
pip3 install --no-index --find-links=. pymongo --安装pymongo库
金仓的Python驱动可以到金仓官网下载,需要找和Python对应的版本
以下是Python脚本内容:
import pymongo
import psycopg2
import concurrent.futures
from psycopg2 import pool
import logging
from urllib.parse import quote_plus
import os # 初始化日志记录
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S') # MongoDB设置
username='admin'
password='SCJGscjg@123'
host='10.253.228.41'
port='27017'
encoded_username = quote_plus(username)
encoded_password = quote_plus(password)
uri = f"mongodb://{encoded_username}:{encoded_password}@{host}:{port}/"
mongo_client = pymongo.MongoClient(uri)
mongo_db = mongo_client['admin']
mongo_collection = mongo_db['admin'] # 连接池设置
kb_pool = psycopg2.pool.ThreadedConnectionPool(
minconn=1,
maxconn=20,
host="10.253.228.110",
database="mongo",
user="system",
password="1",
port="54322"
) # 偏移量存储文件
OFFSET_FILE = 'offset.txt' def read_offset():
if os.path.exists(OFFSET_FILE):
with open(OFFSET_FILE, 'r') as f:
return int(f.read().strip())
return 0 def write_offset(offset):
with open(OFFSET_FILE, 'w') as f:
f.write(str(offset)) def batch_insert(mongo_data):
kb_conn = None
try:
kb_conn = kb_pool.getconn()
with kb_conn.cursor() as kb_cursor:
for data in mongo_data:
id_value = data['_id']
image_data = data['image']
insert_query = "INSERT INTO dzzzwj(id, image) VALUES (%s, %s)"
kb_cursor.execute(insert_query, (id_value, image_data))
kb_conn.commit()
return True
except Exception as e:
logging.error(f"批量插入错误: {e}")
return False
finally:
if kb_conn:
kb_pool.putconn(kb_conn) def main():
batch_size = 80
offset = read_offset()
executor = concurrent.futures.ThreadPoolExecutor(max_workers=8) try:
while True:
mongo_data = list(mongo_collection.find().skip(offset).limit(batch_size))
if not mongo_data:
break future = executor.submit(batch_insert, mongo_data)
future.add_done_callback(lambda f, offset=offset: (
logging.info(f"Batch completed with offset {offset}") if f.result() else logging.error(f"Batch failed with offset {offset}"),
write_offset(offset + batch_size) if f.result() else None
))
offset += batch_size if future.result() else 0
except Exception as e:
logging.error(f"主循环错误: {e}")
finally:
executor.shutdown(wait=True)
mongo_client.close()
kb_pool.closeall()
logging.info("资源已清理完毕。") if __name__ == "__main__":
main()
这段代码思路:
(1)连接MongoDB和kingbase数据;
(2)因为MongoDB数据量比较大,并且需要断点续传,索引用了分页和排序;
(3)数据成功插入金仓数据库后,增加偏移量,并且将当前偏移量记录在offset.txt里面,以便脚本停了,可以再重启接着迁数据;
因为二进制数据从MongoDB和金仓数据查询出来的内容看着不一样,所以下面的代码是计算两边数据md5值对比的简单代码
import pymongo
import ksycopg2
import base64
import hashlib def compute_hash(data):
return hashlib.md5(data).hexdigest() mongo_client = pymongo.MongoClient('mongodb://127.0.0.1:27017/')
mongo_db = mongo_client['admin']
mongo_collection = mongo_db['mongodb'] database = "test"
user = "system"
password = "1"
host = "127.0.0.1"
port = "54322" conn = ksycopg2.connect(database=database, user=user, password=password, host=host, port=port) cursor = conn.cursor() mongo_data = mongo_collection.find()
print(mongo_data) # 插入到 kingbase
for data in mongo_data:
id_value = data['_id']
image_data = data['image'] #image_data = base64.b64encode(base64_data).decode('utf-8') image_data_byte = image_data
if isinstance(image_data, bytes):
mongo_hash = compute_hash(image_data_byte)
print(mongo_hash) #image_data = base64.b64encode(base64_data).decode('utf-8')
if id_value and image_data:
insert_query = "INSERT INTO zzwj(_id, image) VALUES (%s, %s)"
cursor.execute(insert_query, (id_value, image_data)) # 提交事务
conn.commit() cursor.execute("select _id, image from zzwj")
rows = cursor.fetchall() for row in rows:
_id = row[0]
image_byte = row[1] pg_hash = compute_hash(image_byte)
print(pg_hash) # 关闭连接
cursor.close()
conn.close()
mongo_client.close()
用Python脚本迁移MongoDB数据到金仓-kingbase数据库的更多相关文章
- 金仓Kingbase数据库网页数据维护分析工具
金仓Kingbase是优秀的国产数据库产品,在能源,政务,国防等领域广泛使用, 现在TreeSoft数据库管理系统已支持Kingbase了,直接在浏览器中就可以操作查看Kingbase数据了,十分方便 ...
- Delphi中使用python脚本读取Excel数据
Delphi中使用python脚本读取Excel数据2007-10-18 17:28:22标签:Delphi Excel python原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 . ...
- python脚本批量生成数据
在平时的工作中,经常会遇到造数据,特别是性能测试的时候更是需要大量的数据.如果一条条的插入数据库或者一条条的创建数据,效率未免有点低.如何快速的造大量的测试数据呢?在不熟悉存储过程的情况下,今天给大家 ...
- 除了binlog2sql工具外,使用python脚本闪回数据(数据库误操作)
利用binlog日志恢复数据库误操作数据 在人工手动进行一些数据库写操作的时候(比方说数据修改),尤其是一些不可控的批量更新或删除,通常都建议备份后操作.不过不怕万一,就怕一万,有备无患总是好的.在线 ...
- 使用python脚本批量造数据
本篇将采用 Python 脚本的方式进行批量给mysql造数据. 为了使 Python 可以连上数据库(MySQL),并且可以与数据库交互(增删改查等操作),则需要安装 MySQL 客户端操作库. ...
- Rocky4.2下安装金仓v7数据库(KingbaseES)
1.准备操作系统 1.1 系统登录界面 1.2 操作系统版本信息 jdbh:~ # uname -ra Linux jdbh -x86_64 # SMP Fri Dec :: CST x86_64 G ...
- 润乾配置连接kingbase(金仓)数据库
问题背景 客户根据项目的不同,使用润乾连接的数据库类型各种各样,此文针对前几日使用润乾设计器连接kingbase金仓数据库做一个说明. kingbase金仓数据库是一款国产数据库,操作方式和配置 ...
- 如何用Python脚本从文件读取数据?
最近自学Python的进度比较慢,工作之余断断续续的看着效率比较低,看来还是要狠下心来每天进步一点点. 还记得前段时间陈大猫提了一口"先实现用python读取本地文件",碰巧今天看 ...
- python中读取mongodb数据并保存为csv格式的文件
import pandas as pd import matplotlib.pyplot as plt import pymongo %matplotlib inline # 连接mongodb数据库 ...
- 使用Python脚本操作MongoDB的教程
Reference: http://www.jb51.net/article/64225.htm
随机推荐
- spring cloud 学习笔记 服务注册与发现(二)
前言 服务注册与发现的学习.这个其实是微服务的核心了,因为微服务的一个重要理念就是将项目拆分,达到解耦的地步.那么如何把这些服务联系到一起就很关键. 如果一个服务到另外一个服务通过ip地址之间访问,虽 ...
- 重走py 之路 ——列表(一)
前言 因为最近公司有python项目维护,所以把python的基础入门的书整理一遍,因为有些忘记了,同时在看<<python编程>>这本书的时候觉得对有基础的有很多的赘余,打算 ...
- native react 代码智能提示
背景 在vscode 中,虽然有插件可以达到代码提示的效果但是不是很嗨. 所以加上这些: 全局安装typings: npm install typings -g 1 安装react和react-nat ...
- 什么是token,为什么需要token
1.为什么需要token 随着互联网的发展,为了更安全,以及更好的用户体验,逐渐产生了token这个技术方案 之所以使用token是因为http/https协议本身是无状态的,不能进行信息的存储 (c ...
- 如何用 Serverless 低成本打造个人专属网盘?
简介:想要做个网盘不知如何开始,不妨花3分钟读读这篇,看看如何借助 Serverless ,低成本的做一个"不限制网速.无限扩展.同时支持数百种文件格式在线预览.编辑.协作"的专 ...
- 一文总结Java\JDK 17发布的新特性
简介: JDK 17已经于2021年3月16日如期发布.本文介绍JDK 17新特性.JDK 17于2021年9月14日正式发布(General-Availability Release).JDK 1 ...
- [Go] 获得一个整数范围区间的随机数 (golang)
示例:0,1 随机 package main import "fmt" import "math/rand" import "time" f ...
- dotnet 5 的 bin 文件夹下的 ref 文件夹是做什么用的
本文来和大家聊聊在 dotnet 5 和 dotnet 6 或更高版本的 dotnet 构建完成,在 bin 文件夹下,输出的 ref 文件夹.在此文件夹里面,将会包含项目程序集同名的 dll 文件, ...
- pandas:时间序列数据的周期转换
时间序列数据是数据分析中经常遇到的类型,为了更多的挖掘出数据内部的信息,我们常常依据原始数据中的时间周期,将其转换成不同跨度的周期,然后再看数据是否会在新的周期上产生新的特性. 下面以模拟的K线数据为 ...
- 记录Notion API Authorization中的一个坑
正文 Notion官方文档的Authorization部分提到: In your integration code, include the token in the Authorization he ...