将文件上传到MinIO对象存储后,MinIO会将文件存储为对象(.meta文件),并为每个对象生成相应的元数据。元数据是描述对象的属性和信息的数据。
通常,元数据包括对象的名称、大小、创建日期等。 在MinIO中,对象的元数据存储在独立的数据库中,而不是直接存储在文件本身中。
因此,从MinIO中检索文件时,将得到一个包含文件元数据的对象。 如果您希望访问原始文件内容,您可以使用MinIO提供的API或客户端工具来检索对象,并将其保存为原始文件格式。
因旧系统改造,需要将原来的服务器上的文件迁移到MinIO,了解后发现无法直接迁移原文件到MinIO,所以想到通过脚本调用MinIO的API上传文件。
先上代码
import pymysql
import os
import paramiko
from minio import Minio
from minio.error import S3Error
from stat import S_ISDIR
#链接mysql获取需要上传的文件名
def get_sop_url():
# 连接到 MySQL 数据库
conn = pymysql.connect(host=mysql_server, port=mysql_port, user=mysql_user, password=mysql_pwd, db=db_name)
# 创建一个游标对象
cursor = conn.cursor()
# 执行查询语句
cursor.execute("select SUBSTRING(sop,25,LENGTH(sop)) sop from process_sop where sop LIKE '%image%'")
# 获取查询结果
results = [row[0] for row in cursor.fetchall()]
# 关闭游标对象
cursor.close()
# 关闭数据库连接
conn.close()
print(len(results))
return results
# 连接到远程服务器
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(results, 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)
file_name = item.filename
if S_ISDIR(item.st_mode):
# 如果是文件夹,则补充url,递归调用函数处理子文件夹
upload_png_files(results, ssh, item_path + '/', bucket_name, os.path.join(minio_path, file_name + "/"))
# elif file_name.lower().endswith('.png'): # 通过文件后缀上传
elif file_name in results: # 通过mysql查询的文件名对比上传
# 如果是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)
# 设置要上传的图像文件的元数据
metadata = {
"Content-Type": "image/png",
"X-Amz-Meta-Description": "This is a manually uploaded image"
}
content_type = "image/png"
# 构建MinIO中的对象键
object_name = os.path.join(minio_path, os.path.relpath(item_path, remote_path))
# 上传图像文件
client.fput_object(bucket_name, object_name, local_path, content_type, metadata)
print(f"{item.filename} upload success to minio")
# 上传后及时清除提高效率
results.remove(file_name)
# 删除本地临时文件
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/"
# 本地路径
local_path_prefix = "E://temp/"
# minio服务器
minio_server = "ip:port"
minio_user = "账号"
minio_pwd = "密码"
bucket_name = "pub"
minio_path = "upload/"
# mysql
mysql_server = "你的mysql数据库ip"
mysql_port = 3306
mysql_user = "root"
mysql_pwd = "root"
db_name = "db_name"
# 链接需要迁移文件的源服务器
ssh = connect_to_remote_server(hostname, username, password)
# 链接mysql获取需要上传的文件名
results = get_sop_url(mysql_server, mysql_port, mysql_user, mysql_pwd, db_name)
# 上传文件
upload_png_files(results, ssh, remote_path, bucket_name, minio_path)
ssh.close()
高版本的MinIO依赖中已经不使用ResponseError了
所以下面会报错“ImportError cannot import name 'ResponseError'”
from minio.error import ResponseError
应该使用
from minio.error import S3Error
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)
这两种方式都可以解决类型识别问题
Metadata 的 Content-Type 是指对象的元数据的类型,而 content-type 是指对象的内容类型。 它可以是任何类型,但通常是 JSON 或 XML。它包含有关对象的信息,例如对象的创建时间、修改时间、大小等。
content-type 是指对象的内容类型,它可以是任何类型,但通常是文本、图像、视频或音频。它告诉浏览器如何处理对象。
注意:下图显示的是Content-Type,不是Metadata 的 Content-Type。
因为没有提前查看空间磁盘,导致大批量上传时磁盘空间不够,又重新跑了两天脚本。
1、查看容器映射的宿主机路径命令:
#docker inspect <容器ID或name>
docker inspect 8192c5361de1
2、查看宿主机空间分布情况:
df -hl
3、我是将原文件迁移到新的路径,重新docker run 启动minio,指定新的路径,没有尝试修改配置文件的方法,有用过的也请评论告知一下。
4、启动服务后别忘记修改bucket的访问策略。
官方文档API