遇到的一些问题:
1、paramiko使用不熟悉
class SSHClient:
def __init__(self, host: str, port: int, user, pwd):
self.host = host
self.port = port
self.__channel = None
self.user = user
self.pwd = pwd
# 7-bit C1 ANSI sequences
self.__ansi_escape = re.compile(r'''
\x1B # ESC
(?: # 7-bit C1 Fe (except CSI)
[@-Z\-_]
| # or [ for CSI, followed by a control sequence
[
[0-?]* # Parameter bytes
[ -/]* # Intermediate bytes
[@-~] # Final byte
)
''', re.VERBOSE)
self.__ssh = paramiko.SSHClient()
self.__ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.__ssh.connect(self.host, username=user, password=pwd, port=self.port)
tran = self.__ssh.get_transport()
self.sftp = paramiko.SFTPClient.from_transport(tran)
def __del__(self):
self.__close()
# ------获取远端linux主机上指定目录及其子目录下的所有文件------
def get_all_files_in_remote_dir(self, remote_dir):
# 保存所有文件的列表
all_files = list()
# 去掉路径字符串最后的字符'/',如果有的话
if remote_dir[-1] == '/':
remote_dir = remote_dir[0:-1]
# 获取当前指定目录下的所有目录及文件,包含属性值
files = self.sftp.listdir_attr(remote_dir)
for x in files:
# remote_dir目录中每一个文件或目录的完整路径
filename = remote_dir + '/' + x.filename
# 如果是目录,则递归处理该目录,这里用到了stat库中的S_ISDIR方法,与linux中的宏的名字完全一致
if S_ISDIR(x.st_mode):
all_files.extend(self.get_all_files_in_remote_dir(filename))
else:
all_files.append(filename)
return all_files
def sftp_get_dir(self, remote_dir, local_dir):
# 获取远端linux主机上指定目录及其子目录下的所有文件
all_files = self.get_all_files_in_remote_dir(remote_dir)
# 依次get每一个文件
for x in all_files:
filename = x.split('/')[-1]
local_filename = os.path.join(local_dir, filename)
print(u'获取文件%s传输中...' % filename)
self.sftp.get(x, local_filename)
print('******************************** 传输结束 ********************************')
def put(self, local, remote):
self.sftp.put(local, remote)
def get(self, remote, local):
self.sftp.get(remote, local)
def exec(self, cmd: str, end_str=('# ', '$ ', '? ', '% ', '#', '$', '?', '%'), is_recv=True, timeout=5) -> str:
"""
功能描述:执行命令
:param cmd: shell命令
:param end_str: 提示符
:param timeout: 超时间时间
:return: 命令执行结果
"""
if not self.__channel:
self.__channel = self.__ssh.invoke_shell(term='xterm', width=4096, height=48)
time.sleep(0.1)
self.__channel.recv(4096).decode()
if cmd.endswith('\n'):
self.__channel.send(cmd)
else:
self.__channel.send(cmd + '\n')
if end_str is None:
return self.__recv_without_end(cmd, timeout)
if is_recv:
result = self.__recv(end_str, timeout)
begin_pos = result.find('\r\n')
end_pos = result.rfind('\r\n')
if begin_pos == end_pos:
return ''
return result[begin_pos + 2:end_pos]
def __recv_without_end(self, cmd, timeout):
"""
功能描述:接收命令执行结果,不进行任何比对。
:param cmd: 命令
:param timeout:超时时间,最长等待3秒
:return: 命令执行结果
"""
out_str = ''
if timeout > 3:
timeout = 3
max_wait_time = timeout * 1000
self.__channel.settimeout(0.1)
while max_wait_time > 0.0:
try:
start = time.perf_counter()
out = self.__channel.recv(1024 * 1024).decode()
out_str = out_str + out
max_wait_time = max_wait_time - (time.perf_counter() - start) * 1000
except socket.timeout:
max_wait_time -= 100
return out_str
def __recv(self, end_str, timeout) -> str:
"""
功能描述:根据提示符,接收命令执行结果
:param end_str: 预期结果结尾
:param timeout: 超时间
:return: 命令执行结果,去除命令输入提示符
"""
out_str = ''
max_wait_time = timeout * 1000
self.__channel.settimeout(0.05)
while max_wait_time > 0.0:
try:
out = self.__channel.recv(1024 * 1024).decode(encoding='utf-8', errors='ignored')
if not out or out == '':
continue
out_str = out_str + out
match, result = self.__match(out_str, end_str)
if match is True:
return result.strip()
else:
max_wait_time -= 50
except socket.timeout:
max_wait_time -= 50
raise Exception('recv data timeout')
def __match(self, out_str: str, end_str: list) -> (bool, str):
result = self.__ansi_escape.sub('', out_str)
for it in end_str:
if result.endswith(it):
return True, result
return False, result
def __close(self):
if not self.__ssh:
return
self.__ssh.close()
self.__ssh = None
2、定时器使用
3、sqlAlchmey使用
增删查改的使用
4、flask数据库迁移
flask db init
flask db migrate
flask db upgrade
但不支持删除列,最好使用mysql
5、解决重复写入数据库
添加unique约束,可以添加联合unique
6、分页
分前端分页和后端分页
7、思考工具如何完善
如何对数据更进一步分析