前言
将文件上传到MinIO对象存储后,MinIO会将文件存储为对象(.meta文件),并为每个对象生成相应的元数据。元数据是描述对象的属性和信息的数据。
通常,元数据包括对象的名称、大小、创建日期等。 在MinIO中,对象的元数据存储在独立的数据库中,而不是直接存储在文件本身中。
因此,从MinIO中检索文件时,将得到一个包含文件元数据的对象。 如果您希望访问原始文件内容,您可以使用MinIO提供的API或客户端工具来检索对象,并将其保存为原始文件格式。
需求
因旧系统改造,需要将原来的服务器上的文件迁移到MinIO,了解后发现无法直接迁移原文件到MinIO,所以想到通过脚本调用MinIO的API上传文件。
实现
先上代码
import os
import paramiko
from minio import Minio
from minio.error import S3Error
from stat import S_ISDIR
# 连接到远程服务器
def connect_to_remote_server(hostname, username, password):
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
ssh.connect(hostname, username=username, password=password)
return ssh
# 递归遍历文件夹并上传PNG文件到MinIO
def upload_png_files(ssh, remote_path, bucket_name, minio_path):
sftp = ssh.open_sftp()
try:
# 遍历远程路径下的文件和文件夹
for item in sftp.listdir_attr(remote_path):
item_path = os.path.join(remote_path, item.filename)
if S_ISDIR(item.st_mode):
# 如果是文件夹,则补充url,递归调用函数处理子文件夹
upload_png_files(ssh, item_path+'/', bucket_name, os.path.join(minio_path, item.filename+"/"))
elif item.filename.lower().endswith('.png'):
# 如果是PNG文件,则上传到MinIO,可根据需求修改
local_path = os.path.join(local_path_prefix, os.path.relpath(item_path, remote_path))
os.makedirs(os.path.dirname(local_path), exist_ok=True)
sftp.get(item_path, local_path)
print(f"{item.filename} download success")
# 创建MinIO客户端对象
client = Minio(minio_server, access_key=minio_user, secret_key=minio_pwd, secure=False)
# 构建MinIO中的对象键
object_name = os.path.join(minio_path, os.path.relpath(item_path, remote_path))
# 上传图像文件
client.fput_object(bucket_name, object_name, local_path)
print(f"{item.filename} upload success to minio")
# 删除本地临时文件
os.remove(local_path)
except S3Error as err:
print(err)
finally:
sftp.close()
# 调用函数连接到远程服务器并上传所有PNG文件到MinIO指定路径
#远程服务器
hostname = "你的源ip"
username = "账号"
password = "密码"
remote_path = "/home/centos/upload/files/20200102/"
#本地路径
local_path_prefix = "E://temp/"
#minio服务器
minio_server = "ip:port"
minio_user = "账号"
minio_pwd = "密码"
bucket_name = "pub"
minio_path = "upload/"
ssh = connect_to_remote_server(hostname, username, password)
upload_png_files(ssh, remote_path, bucket_name, minio_path)
ssh.close()
踩坑记录
坑1——依赖导入
高版本的MinIO依赖中已经不使用ResponseError了
所以下面会报错“ImportError cannot import name 'ResponseError'”
from minio.error import ResponseError
应该使用
from minio.error import S3Error
坑2——SSL链接
client = Minio("ip:port",access_key="minio",secret_key="minio")
以上代码默认启用https,报错如下:
urllib3.exceptions.MaxRetryError:
HTTPSConnectionPool(host='10.11.1.62', port=9000):
Max retries exceeded with url: /pub?location= (Caused by SSLError(SSLError(1, '[SSL: WRONG_VERSION_NUMBER] wrong version number (_ssl.c:1129)')))
需要使用http,加上 secure=False
client = Minio("ip:port",access_key="minio",secret_key="minio",secure=False)
官方文档API