背景
随着业务数据的不断增涨,导致存储空间不足及查询效率的问题不断出现,于是做了个生产数据裁剪的项目并通过shell 脚本实现了每月自动化裁剪。目前已经正常运行近3年左右。最近因裁剪的表不断增加,导致原来的shell 脚本无法满足近期的自动化任务。因此计划用Python语言重写脚本,同时对一些步骤进行优化,正好锻炼一下自己Python的编程能力。
裁剪项目逻辑处理流程分4步:
- 1、Oracle Expdp 命令将裁剪分区导出;
- 2、通过scp、rsync命令将dmp文件传输到历史库服务器;
- 3、Oracle Impdp 命令将裁剪数据导入历史库;
- 4、使用truncate partition 将裁剪分区数据进行清除;
因自己的Python代码能力一般,在处理传输expdp 导出的dmp文件时,技术卡壳了。
技术卡壳:
规划通过A服务器作为管理端,对B服务器的生产数据库进行Expdp ,然后将B服务器产生的DMP文件传输到C服务器中的历史库中。
目前的技术卡点:如何从A服务器命令调用B服务器往C服务器传输dmp文件,因为需要输入用户名和密码。由于自己的Pyhon代码能力还是很欠缺,只能翻网页找解决方案,千篇一律,各种复制粘贴。最近deepseek 比较火,尝试问一下,看看能不能解决自己的问题。
需求
“帮我下一段python代码,实现 从A服务器,连接到B服务器,然后把B服务器的文件直接传输到C服务器,仅传输一次,不通过A服务器中转,考虑安全性不使用免密,考虑大文件上10GB左右”
deepseek
提出需求

分析过程结合很全面,确实前面刚提过使用expect 命令

代码方案:

代码如下,直观评价代码比我写的规范,然后结合上面的分析过程很容易理解代码
import paramiko
import logging
import os
from tempfile import mkstemp
# 配置日志
logging.basicConfig()
logger = logging.getLogger("SecureTransfer")
logger.setLevel(logging.INFO)
def secure_transfer(b_host, b_user, b_password,
c_host, c_user, c_password,
source_path, dest_path,
port=22):
"""
安全传输流程:
1. A服务器连接B服务器(使用密码认证)
2. 在B服务器创建临时安全目录
3. 通过加密通道传输C服务器密码到B服务器
4. 在B服务器使用sshpass+rsync传输文件
5. 清理B服务器上的临时凭证
"""
ssh = paramiko.SSHClient()
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
sftp = None
try:
# 连接B服务器
logger.info(f"🔑 Connecting to B server {b_host}...")
ssh.connect(hostname=b_host, username=b_user, password=b_password)
# 创建临时安全目录
temp_dir = "/tmp/secure_transfer_" + os.urandom(8).hex()
ssh.exec_command(f"mkdir -m 700 {temp_dir}")
# 创建临时密码文件
_, local_temp = mkstemp()
with open(local_temp, 'w') as f:
f.write(c_password)
# 上传密码文件到B服务器
remote_pass_file = f"{temp_dir}/c_password"
sftp = ssh.open_sftp()
sftp.put(local_temp, remote_pass_file)
sftp.chmod(remote_pass_file, 0o600)
os.unlink(local_temp) # 删除本地临时文件
# 构建传输命令
rsync_cmd = f"""
sshpass -f {remote_pass_file} \
rsync -avz --partial --progress --bwlimit=100000 \
-e 'ssh -o StrictHostKeyChecking=no -T -o ServerAliveInterval=60' \
{source_path} {c_user}@{c_host}:{dest_path}
"""
# 执行传输命令
logger.info("🚀 Starting secure transfer...")
stdin, stdout, stderr = ssh.exec_command(rsync_cmd, get_pty=True)
# 实时显示进度
while True:
line = stdout.readline()
if not line:
break
logger.info(line.strip())
# 检查执行结果
exit_status = stdout.channel.recv_exit_status()
if exit_status != 0:
error_msg = stderr.read().decode()
logger.error(f"❌ Transfer failed: {error_msg}")
raise RuntimeError("Transfer failed")
logger.info("✅ Transfer completed successfully!")
except Exception as e:
logger.error(f"⚠️ Critical error: {str(e)}")
raise
finally:
# 清理操作
try:
if sftp: sftp.remove(remote_pass_file)
ssh.exec_command(f"rm -rf {temp_dir}")
except:
pass
ssh.close()
if __name__ == "__main__":
# B服务器认证信息(建议从环境变量获取)
B_HOST = "b_server_ip"
B_USER = "b_username"
B_PASSWORD = os.environ.get("B_PASSWORD") # 从环境变量读取
# C服务器认证信息(建议从加密存储获取)
C_HOST = "c_server_ip"
C_USER = "c_username"
C_PASSWORD = os.environ.get("C_PASSWORD") # 从环境变量读取
# 文件路径
SOURCE_PATH = "/path/on/b_server/large_file.dat"
DEST_PATH = "/path/on/c_server/"
secure_transfer(
b_host=B_HOST,
b_user=B_USER,
b_password=B_PASSWORD,
c_host=C_HOST,
c_user=C_USER,
c_password=C_PASSWORD,
source_path=SOURCE_PATH,
dest_path=DEST_PATH
)
代码使用说明,很人性化,参数介绍清楚

使用前准备

还有扩展功能


直观感受
- 1、个性化很强,思路很清晰,同时也为我提供了更多思路;
- 2、代码很全面,密码安全(我都没怎么考虑);
- 3、很惊艳;
调试代码运行
- 设置环境变量里的密码
[oracle@A_db py_main]$ vim ~/.bash_profile
export B_PASSWORD="oracle"
export C_PASSWORD="oracle"
- 配置(B、C)服务器IP、用户、源文件、目标目录
if __name__ == "__main__":
# B服务器认证信息(建议从环境变量获取)
B_HOST = "192.168.5.100"
B_USER = "oracle"
B_PASSWORD = os.environ.get("B_PASSWORD") # 从环境变量读取
# C服务器认证信息(建议从加密存储获取)
C_HOST = "192.168.5.64"
C_USER = "oracle"
C_PASSWORD = os.environ.get("C_PASSWORD") # 从环境变量读取
# 文件路径
SOURCE_PATH = "/u01/backup/py_cutdat/expdp_dat/2025-02-12.tar.gz"
DEST_PATH = "/u01/backup/py_cutdat/expdp_dat/"
secure_transfer(
b_host=B_HOST,
b_user=B_USER,
b_password=B_PASSWORD,
c_host=C_HOST,
c_user=C_USER,
c_password=C_PASSWORD,
source_path=SOURCE_PATH,
dest_path=DEST_PATH
)
- 开始执行脚本
[oracle@A_db py_main]$ python3 transfer_script.py
INFO:SecureTransfer: Connecting to B server 192.168.5.100...
INFO:SecureTransfer: Starting secure transfer...
INFO:SecureTransfer:sending incremental file list
INFO:SecureTransfer:2025-02-12.tar.gz
203341299 100% 60.44MB/s 0:00:03 (xfer#1, to-check=0/1)
INFO:SecureTransfer:
INFO:SecureTransfer:sent 203409660 bytes received 31 bytes 58117054.57 bytes/sec
INFO:SecureTransfer:total size is 203341299 speedup is 1.00
INFO:SecureTransfer:✅ Transfer completed successfully!
- 登录C服务器验证
[oracle@C_db expdp_dat]$ pwd
/u01/backup/py_cutdat/expdp_dat
[oracle@C_db expdp_dat]$ ll
总用量 198576
-rw-r--r-- 1 oracle oinstall 203341299 2月 14 14:34 2025-02-12.tar.gz
小结
简直难以置信!这次运行代码,我仅仅添加了几个参数,没有对代码本身做任何调整,它就顺利跑通了!这结果着实让我惊掉了下巴 。而且,这段代码的规范程度极高,逻辑缜密,考虑全面,输出的结果也十分详尽。更令人赞叹的是,它还具备出色的扩展性,潜力无限。从这一刻起,有了 DeepSeek 的加持,我感觉自己都能底气十足地自称 “资深 Python 技术大牛” 了。
这次经历让我深刻领悟到:“AI 绝非发展的阻碍,而是强大的助力。身处当下,我们必须顺应时代的潮流,欣然接纳时代孕育的产物,并熟练掌握运用它们的技巧,从而实现自我能力的提升。”
----- 经验在于多沉淀
欢迎赞赏支持或留言指正





