15、监测数据采集物联网应用开发步骤(11)

news2024/7/4 5:05:10

源码将于最后一遍文章给出下载

  1. 监测数据采集物联网应用开发步骤(10)

程序自动更新开发

前面章节写了部分功能模块开发:

  1. 日志或文本文件读写开发;
  2. Sqlite3数据库读写操作开发;
  3. 定时器插件化开发;
  4. 串口(COM)通讯开发;
  5. TCP/IP Client开发;
  6. TCP/IP Server 开发;
  7. modbus协议开发;

本章节啰嗦些,该解决方案最终业务成品有些需要部署在不同工控机或设备上,在实际应用过程中随时间推移有些需要升级迭代或修改bug,一旦安装部署设备点位达到一定数量,系统自动更新升级就是一个必要的步骤了。笔者开发的业务应用在相应的设备上安装已近千台设备,鉴于此增加了程序自动更新功能模块。

com.zxy.common.Com_Para.py中添加如下内容

#自动更新服务端文件夹地址
urlPath = ""
#程序版本号
version = ""

新建程序版本自动更新类com.zxy.autoUpdate.GetVersion.py
 

#! python3
# -*- coding: utf-8 -
'''
Created on 2017年05月10日
@author: zxyong 13738196011
'''

import urllib.request,datetime
from com.zxy.adminlog.UsAdmin_Log import UsAdmin_Log
from com.zxy.common import Com_Para
from com.zxy.common.Com_Fun import Com_Fun
from com.zxy.interfaceReflect.A01_A1B2C3 import A01_A1B2C3
from com.zxy.z_debug import z_debug
from urllib.parse import urlparse

#监测数据采集物联网应用--程序版本自动更新类
class GetVersion(z_debug):

    def __init__(self):
        pass
    
    #下载文件
    def SaveRemoteFile(self,inputFileName,inputLocalFileName):
        try:
            temResult = urllib.request.urlretrieve(Com_Para.urlPath+"/"+inputFileName,Com_Para.ApplicationPath+Com_Para.zxyPath+inputLocalFileName)
        except Exception as e:
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,repr(e)+"=>"+str(e.__traceback__.tb_lineno))#打印异常信息
            else:
                self.debug_in(repr(e)+"=>"+str(e.__traceback__.tb_lineno))#打印异常信息
        return temResult
    
    #保存版本号文件
    def SaveVersionFile(self,version_no,inputLocalFileName):
        temStrTFileName = Com_Para.ApplicationPath+Com_Para.zxyPath+inputLocalFileName
        temFile = None
        try: 
            temFile = open(temStrTFileName, 'w',encoding=Com_Para.U_CODE)
            temFile.write(version_no)
            temFile.close()
        except Exception as e:
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,repr(e)+"=>"+str(e.__traceback__.tb_lineno))#打印异常信息
            else:
                self.debug_in(repr(e)+"=>"+str(e.__traceback__.tb_lineno))#打印异常信息
        finally:
            if temFile != None:
                temFile.close()
            
    #检测最新版本
    def CheckVersion(self):
        try:
            print("check new version..."+Com_Fun.GetTimeDef())
            #读取服务器端version.txt信息
            temResult = self.GetRequestWeb()
            if temResult == "":
                return 0
            temUL = UsAdmin_Log(Com_Para.ApplicationPath,temResult,0)
            #文件形式版本号管理
            temVersion = temUL.ReadFile(Com_Para.ApplicationPath+Com_Para.zxyPath + "version.txt")
            Com_Para.version = temVersion
            #数据库形式版本号管理
            temVersion = Com_Para.version
            temAryTem = []
            temVersion_No = ""
            temLastFile = ""
            #判断文件是否存在
            if temVersion == "" and temResult != "":
                print("local version none,downloading new version")
                temAryTem = temResult.split("\n")
                for temLine in temAryTem:
                    temLine = temLine.replace("\r","").replace("\n","")
                    temLastFile = temLine
                    if temLine.find("version=") != -1:
                        temVersion_No = temLine
                    elif temLine != "":
                        print("new version file download:"+temLine)
                        self.SaveRemoteFile(temLine,"back/"+temLine)
                        self.CopyFile(temLine)
                        if temVersion_No != "":
                            #文件形式版本管理     
                            self.SaveVersionFile(temVersion_No,"version.txt")
                            #数据库形式版本文件管理
                            #将版本号insert入库 该处代码省略....
                            Com_Para.version = temVersion_No    
                            print("new version updated over:")
                        #如果读到reboot.txt则需要重启设备
                        if temLastFile.strip() == "reboot.txt":
                            self.RebootProgram()
                            return 0
                if temVersion_No != "":
                    #文件形式版本管理     
                    print("new version updated over:")
                    self.SaveVersionFile(temVersion_No,"version.txt")
                    #数据库形式版本文件管理
                    #将版本号insert入库  该处代码省略....
                    Com_Para.version = temVersion_No
            elif temResult != "":
                #数据库形式版本号管理
#                 localVersion = Com_Para.version
                #文件形式版本号管理
                temAryTem = temVersion.split("\n")
                for temLine in temAryTem:
                    temArySub = temLine.split("=")
                    if len(temArySub) > 1 and temArySub[0] == "version":
                        localVersion = temArySub[1]
                        break 
                bFlag = False
                temAryTem = temResult.split("\n")
                for temLine in temAryTem:
                    temLine = temLine.replace("\r","").replace("\n","")
                    temLastFile = temLine
                    temArySub = temLine.split("=")
                    if len(temArySub) > 1 and temArySub[0] == "version":
                        try:
                            if localVersion.find("=") != -1:
                                iLV = int(localVersion.split("=")[1])
                            else:
                                iLV = int(localVersion)
                                
                            if localVersion != "" and iLV >= int(temArySub[1]):
                                bFlag = False
                            else:
                                temVersion_No = temLine
                                bFlag = True
                        except:
                            bFlag = False
                            break
                    else:
                        if bFlag:
                            self.SaveRemoteFile(temLine,"back/"+temLine)
                            self.CopyFile(temLine)
                            if temVersion_No != "":
                                #文件形式版本管理     
                                self.SaveVersionFile(temVersion_No,"version.txt") 
                                #数据库形式版本文件管理  
                                #将版本号insert入库  该处代码省略....
                                Com_Para.version = temVersion_No
                                print("new version updated over:"+temVersion_No)
                            if temLastFile.strip() == "reboot.txt":
                                self.RebootProgram()
                                return 0
                                    
                if (bFlag and temVersion_No != ""):
                    #文件形式版本管理     
                    self.SaveVersionFile(temVersion_No,"version.txt")
                    #数据库形式版本文件管理  
                    #将版本号insert入库  该处代码省略....
                    Com_Para.version = temVersion_No
                    print("new version updated over:")
                if bFlag and temLastFile.strip() == "reboot.txt":
                    self.RebootProgram()
                    return 0
        except Exception as e:
            if str(type(self)) == "<class 'type'>":
                self.debug_in(self,repr(e)+"=>"+str(e.__traceback__.tb_lineno))#打印异常信息
            else:
                self.debug_in(repr(e)+"=>"+str(e.__traceback__.tb_lineno))#打印异常信息
        return 1
    
    #重启设备
    def RebootProgram(self):        
        aa = A01_A1B2C3()
        if Com_Para.devsys.lower() == "linux": 
            aa.param_value2 = "reboot -f"
            aa.CmdExecLinux()
        else:
            aa.param_value2 = "shutdown -r"
            aa.CmdExecWin()
        
    #文件更新
    def CopyFile(self,inputWebFile):
        temAryTem = inputWebFile.split("\n")
        for temLine in temAryTem:
            if temLine.find("=") == -1:
                aa = A01_A1B2C3()
                temFileName = temLine[0:temLine.find(".")]
                temFileAtt = temLine[temLine.find("."):len(temLine)].upper()
                if temFileAtt.upper() == ".ZIP":
                    aa.param_value2 = "unzip -o "+Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temLine+" -d "+Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temFileName+Com_Para.zxyPath
                    aa.param_value3 = Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temLine
                    aa.param_value4 = Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temFileName+Com_Para.zxyPath
                    #利用命令进行解压缩
                    #aa.CmdExecLinux()
                    #利用python自带解压缩模块
                    aa.unzip_file()                     
                    if Com_Para.devsys.lower() == "linux":                 
                        aa.param_value2 = "cp -rf "+Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temFileName+Com_Para.zxyPath+"* "+Com_Para.ApplicationPath+Com_Para.zxyPath
                    else:
                        aa.param_value2 = "xcopy "+Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temFileName+Com_Para.zxyPath+"*.* "+Com_Para.ApplicationPath+" /E /Y"
                    aa.CmdExecLinux()
                #执行sql语句
                elif temFileAtt.upper() == ".SQL":
                    aa.RunSqlFile(Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temLine)
                #执行更新数据接口
                elif temFileAtt.upper() == ".JSON":
                    #JSON业务数据进行数据库结构更改或升级
                    pass
                else:
                    if Com_Para.devsys.lower() == "linux":                 
                        aa.param_value2 = "cp -rf "+Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temLine+" "+Com_Para.ApplicationPath+Com_Para.zxyPath
                    else:
                        aa.param_value2 = "copy "+Com_Para.ApplicationPath+Com_Para.zxyPath+"back"+Com_Para.zxyPath+temLine+" "+Com_Para.ApplicationPath+Com_Para.zxyPath+" /Y"
                    aa.CmdExecLinux()
    
    #inputFlag网络链接是否正常
    def set_dSockList(self,inputFlag):
        urlp = urlparse(Com_Para.urlPath)
        if Com_Para.urlPath == "":
            return None                
        key = str(urlp.netloc.replace(":","|")) 
        #存在
        if key not in list(Com_Para.dSockList.keys()):
            Com_Para.dSockList[key] = [0,datetime.datetime.now()]
        if inputFlag == False:
            objAry = Com_Para.dSockList[key]
            if objAry[0] <= 10:
                objAry[0] = objAry[0] + 1
            objAry[1] = datetime.datetime.now()
            Com_Para.dSockList[key] = objAry
        else:
            Com_Para.dSockList[key] = [0,datetime.datetime.now()]    
    
    #判断上次链接时间频率是否合规
    def judge_dSock(self):
        urlp = urlparse(Com_Para.urlPath)
        if Com_Para.urlPath == "":
            return False                
        key = str(urlp.netloc.replace(":","|")) 
        if key not in list(Com_Para.dSockList.keys()):
            Com_Para.dSockList[key] = [0,datetime.datetime.now()]
        objAry = Com_Para.dSockList[key]
        starttime = datetime.datetime.now()
        if objAry[0] <= 3:
            return True
        elif objAry[0] > 4 and starttime >= objAry[1] + datetime.timedelta(hours=12):
            return True
        else:
            return False
            
    def GetRequestWeb(self):
        temResult = ""
        try:
            #判断上次链接时间频率是否合规
            if not self.judge_dSock():
                return ""
            resp = urllib.request.urlopen(Com_Para.urlPath+"/version.txt",timeout=5)
            temResult = resp.read().decode(Com_Para.U_CODE)        
        except Exception as e:
            temLog = ""
            if str(type(self)) == "<class 'type'>":
                temLog = self.debug_info(self)+repr(e)
            else:
                temLog = self.debug_info()+repr(e)
            uL = UsAdmin_Log(Com_Para.ApplicationPath, temLog+"=>"+str(e.__traceback__.tb_lineno))
            uL.WriteLog()
            temResult = ""
            self.set_dSockList(False)
        return temResult

新建操作系统执行指令接口类com.zxy.interfaceReflect.A01_A1B2C3.py

#! python3
# -*- coding: utf-8 -
'''
Created on 2017年05月10日
@author: zxyong 13738196011
'''

import os, sys,zipfile,subprocess,tempfile
from urllib.parse import unquote
from com.zxy.common import Com_Para
from com.zxy.common.Com_Fun import Com_Fun
from com.zxy.z_debug import z_debug

#监测数据采集物联网应用--操作系统执行指令接口类
class A01_A1B2C3(z_debug):
    strResult        = ""
    session_id       = ""
    param_name       = ""
    param_value1     = None  #1:同步更新设备时间
    param_value2     = None  #当前时间
    param_value3     = None
    param_value4     = None
    param_value5     = None
    param_value6     = None
    param_value7     = None
    param_value8     = None
    param_value9     = None
    param_value10    = None
    #是否继续执行 1:继续执行 0:中断执行
    strContinue      = "0"
    strCmdValue     = ""
    
    def __init__(self):
        pass
        
    def init_start(self):       
#         /**************************************************/
#         //示例: 此处写业务逻辑,最后给 param_name,param_value1....重新赋值 
#         // param_name += Com_Fun.Get_New_GUID()
#         // param_value1 += Com_Fun.Get_New_GUID()
#         // param_value2 += Com_Fun.Get_New_GUID()
#         // ......
        
#         /**************************************************/
#         //示例:若业务逻辑判断失败,不发送数据库接口请求并返回失败信息
        #strContinue      = "0" 表示拦截器判断接口执行结束,不需要入库操作,直接返回信息
        temValue = ""
        self.strContinue = "0"
        if self.param_value1 == "100" and Com_Para.devsys == "linux":
            temValue = self.CmdExecLinux(self)
            self.strResult = "命令结果:\r\n"
            for temR in temValue:
                self.strResult = self.strResult+temR.decode(Com_Para.U_CODE)+"\r\n"
        #100执行命令
        elif self.param_value1 == "100" and Com_Para.devsys == "windows":
            temValue = self.CmdExecWin(self)
            self.strResult = "{\""+self.param_name+"\":[{\"s_result\":\"1\",\"error_desc\":\"命令执行成功"+temValue+"\"}]}"
       
    #利用python自带解压缩
    def unzip_file(self):
        temzipfile = zipfile.ZipFile(self.param_value3, 'r')
        temzipfile.extractall(self.param_value4)        
    
    #重启程序
    def RestartPro(self):
        python = sys.executable
        os.execl(python,python,* sys.argv)
        
    #执行命令(Linux)
    def CmdExecLinux(self):
        out_temp = None
        try:       
            temCommand = unquote(unquote(self.param_value2,Com_Para.U_CODE))
            out_temp = tempfile.SpooledTemporaryFile(max_size=10*1000)
            fileno = out_temp.fileno()
            obj = subprocess.Popen(temCommand,stdout=fileno,stderr=fileno,shell=True)
            obj.wait()            
            out_temp.seek(0)
            temResult = out_temp.readlines()              
        except Exception as e:
            temResult = repr(e)
        finally:
            if out_temp is not None:
                out_temp.close()
        return temResult
    
    #执行命令(Windows)
    def CmdExecWin(self):
        try:
            temCommand = unquote(unquote(self.param_value2,Com_Para.U_CODE))
            temResult = os.popen(temCommand).read()
        except Exception as e:
            temResult = repr(e)
        return temResult
    
    #更新设备时间(Windows)
    def ChangeDateWin(self):
        try:
            temDate = Com_Fun.GetDateInput('%Y-%m-%d', '%Y-%m-%d %H:%M:%S', unquote(unquote(self.param_value2.replace("+"," "),Com_Para.U_CODE)))
            temTime = Com_Fun.GetDateInput('%H:%M:%S', '%Y-%m-%d %H:%M:%S', unquote(unquote(self.param_value2.replace("+"," "),Com_Para.U_CODE)))
            temResult = os.system('date {} && time {}'.format(temDate,temTime))
        except:
            temResult = -1
        return temResult
    
    #更新设备时间(Linux)
    def ChangeDateLinux(self):
        try:            
            #将硬件时间写入到系统时间:
            #hwclock -s
            #将系统时间写入到硬件时间
            #hwclock -w
            temCommand = unquote(unquote("date -s \""+self.param_value2.replace("+"," ").split(" ")[0]+"\"",Com_Para.U_CODE))
            temCommand = unquote(unquote("date -s \""+self.param_value2.replace("+"," ").split(" ")[1]+"\"",Com_Para.U_CODE))
            out_temp = tempfile.SpooledTemporaryFile(max_size=10*1000)
            fileno = out_temp.fileno()
            obj = subprocess.Popen(temCommand,stdout=fileno,stderr=fileno,shell=True)
            obj.wait()
            temCommand = unquote(unquote("hwclock -w",Com_Para.U_CODE))
            obj = subprocess.Popen(temCommand,stdout=fileno,stderr=fileno,shell=True)
            obj.wait()         
            out_temp.seek(0)
            temByt = out_temp.readlines()
            temResult = temByt[0].decode(Com_Para.U_CODE)
            if temResult == "" :
                temResult = "1"
        except Exception as e:
            temResult = "-1"        
        finally:
            if out_temp is not None:
                out_temp.close()
        return temResult

版本更新测试案例MonitorDataCmd.py主文件中编写:

from com.zxy.autoUpdate.GetVersion import GetVersion

在    if __name__ == '__main__':下添加

        #版本更新测试

        Com_Para.urlPath = "http://localhost:8080/testweb/updtest/"

        gv = GetVersion()    

        gv.CheckVersion()

        print("=>版本更新完成")

程序文件新建back文件夹临时存放下载更新包的zip文件;

版本更新服务端文件信息

版本更新服务端版本号信息

运行结果设备端更新之后新增文件

更新文件已下载并自动解压缩成功。

print打印出的内容

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/953558.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

胜券汇:行业持续轮动 缺乏主线下关注反转预期的方向

前史行情4年一轮回&#xff0c;中心在于微观环境的类似性。首要&#xff0c;复盘前史&#xff0c;2016-2019年和2020年至今的行情走势较为类似&#xff0c;历经约1年半的长牛&#xff0c;约1年的长熊&#xff0c;阅历1个季度快速反弹后继续约3个季度的震动期。其次&#xff0c;…

二叉查找树(binary search tree)(难度7)

C数据结构与算法实现&#xff08;目录&#xff09; 答案在此&#xff1a;二叉查找树&#xff08;binary search tree&#xff09;&#xff08;答案&#xff09; 写在前面 部分内容参《算法导论》 基本接口实现 1 删除 删除值为value的第一个节点 删除叶子节点1 删除叶子节…

Jmete+Grafana+Prometheus+Influxdb+Nginx+Docker架构搭建压测体系/监控体系/实时压测数据展示平台+遇到问题总结

背景 需要大批量压测时&#xff0c;单机发出的压力能力有限&#xff0c;需要多台jmeter来同时进行压测&#xff1b;发压机资源不够&#xff0c;被压测系统没到瓶颈之前&#xff0c;发压机难免先发生资源不足的情形&#xff1b;反复压测时候也需要在不同机器中启动压测脚本&…

抖店的入门教程,新手开店后想快速跑通流程,必须要这么做!

我是王路飞。 作为一个在抖音刚开始开店卖货的新手商家&#xff0c;你认为对你来说&#xff0c;什么才是最重要的呢&#xff1f; 根据我做抖店这三四年的经验&#xff0c;以及所带的几百个学生的数据/结果反馈来看&#xff0c;先入门&#xff0c;永远是新手的第一要务。 只有…

股票融资50万一天利息是多少?利率可以给到5%吗?

利息股票融资50万一天利息是多少&#xff0c;需要结合您的融资利率来计算的。比如您的融资利率是8.35%&#xff0c;股票融资50万一天利息计算50万8.35%/360天115.97元&#xff0c;即&#xff1a;股票融资50万&#xff0c;一天的利息是115.97元。 股票融资利率一般是默认在8.35%…

CSRF(跨站请求伪造)和SSRF(服务端请求伪造)漏洞复现:风险与防护方法

这篇文章旨在用于网络安全学习&#xff0c;请勿进行任何非法行为&#xff0c;否则后果自负。 环境准备 一、CSRF&#xff08;跨站请求伪造&#xff09; 示例&#xff1a;假设用户在银行网站A上登录并保持会话活动&#xff0c;同时他也在浏览其他网站。攻击者在一个不可信任…

亚马逊加拿大站儿童床垫SOR安全要求SOR/2016-152

儿童床垫的安全性对于家庭的健康和孩子的成长至关重要。加拿大制定了一系列儿童产品安全法规&#xff0c;其中包括关于儿童床垫的安全要求。本文将介绍亚马逊加拿大站对儿童床垫的SOR安全要求&#xff0c;以帮助消费者选择安全可靠的产品。 本政策适用于与婴儿床、摇篮、婴儿摇…

Go死码消除

概念: 死码消除(dead code elimination, DCE) 是一种编译器优化技术, 作用是在编译阶段去掉对程序运行结果没有任何影响的代码 和 逃逸分析[1],内联优化[2]并称为 Go编译器执行的三个重要优化 效果: 对于 const.go代码如下: package mainimport "fmt"func max(a, b i…

【数据库事务】

数据库事务 何为事务事务的特性原子性 Atomicity一致性 Consistency隔离性 IsolationRead UncommittedRead CommittedRepeatable ReadSerializable 持久性 Durability功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的…

嵌入式学得多拿得少?选好方向最重要!

嵌入式开发确实是一个知识领域非常广泛的行业&#xff0c;涉及到模电、数电、C语言、EDA、单片机、RTOS、ARM、Linux等等众多方面。然而&#xff0c;关于工资少的说法其实是有误导性的。如果按照这种说法&#xff0c;那要学习几年才能达到爱因斯坦的水平了&#xff01; 事实上&…

RTSP/Onvif流媒体视频平台EasyNVR视频平台旧版本视频播放出现花屏情况的处理方法

EasyNVR安防视频云服务是基于RTSP/Onvif协议的流媒体视频平台&#xff0c;可实现设备接入、实时直播、录像、检索与回放、云存储、视频分发、级联等视频能力服务&#xff0c;能分发RTSP、RTMP、HTTP-FLV、WS-FLV、HLS、WebRTC格式的视频流。 有用户反馈&#xff0c;在现场部署…

VR全景对行业发展有什么帮助?VR全景制作需要注意什么?

引言&#xff1a; 虚拟现实&#xff08;Virtual Reality&#xff0c;简称VR&#xff09;早已不再是科幻电影的概念&#xff0c;而是在以惊人的速度改变着我们的世界。VR全景&#xff0c;作为其中的重要组成部分&#xff0c;正为多个行业带来了全新的机遇。 一、VR全景的应用领…

对分库分表进行批量操作

对ShardingJDBC基础了解&#xff1a;https://blog.csdn.net/m0_63297646/article/details/131894472 对批量操作案例&#xff1a;https://blog.csdn.net/m0_63297646/article/details/131843517 分为db0和db1两个库&#xff0c;每个库都有三张订单表&#xff0c;分表键根据年份…

核心交换机的六个基础知识

中午好&#xff0c;我的网工朋友 今天来聊聊核心交换机啊。 首先你要明确一个概念&#xff0c;接入层交换机、汇聚层交换机、核心层交换机并非是交换机的种类或者属性&#xff0c;只是由其所执行的任务来划分的。 从网络拓扑结构来讲&#xff0c;一个计算机网络系统结构需采用…

Soul的社交元宇宙之路,还有多远?

在元宇宙概念爆火的当下&#xff0c;以互联网为依托的虚拟社交逐步为用户承载起其空缺的精神交流与寄托&#xff0c;而在这其中&#xff0c;以“跟随灵魂找到你”为Slogan&#xff0c;主打年轻人社交元宇宙平台的APP--Soul则在这条赛道上凭借着独特的风格&#xff0c;逐步突出重…

Elasticsearch 7.6 - APi基础操作篇

ES7.6-APi基础操作篇 前言相关知识索引相关创建索引查询索引查询所有索引删除索引关闭与打开索引关闭索引打开索引 冻结与解冻索引冻结索引解冻索引 映射相关创建映射查看映射新增字段映射 文档相关(CURD)新增文档根据ID查询修改文档全量覆盖根据ID选择性修改根据条件批量更新 …

移动数据安全案例(MAG)| 好的方案是恰到好处的平衡

某基金公司是由国有商业银行直接发起设立并控股的合资基金管理公司&#xff0c;服务于超过5000万客户&#xff0c;其资产管理规模近2万亿。作为国内头部基金公司&#xff0c;在网络安全和数据安全的建设上已经非常完善。目前已在办公网敏感数据的创建、流转、存储等数据安全生命…

Python钢筋混凝土结构计算.pdf-混凝土构件计算

计算原理&#xff1a; 代码实现&#xff1a; #钢筋混凝土参数 def c_hrb(): global fcuk,HRB,Ec,fc,ft,ftk,Es,fy,fyp,fyk global a1,epsilon_cu fcukEcfcftftk0.0 HRBEsfyfypfyk0.0 #矩形应力图系数a1&#xff0c;C50以下为1.0 a11.0 #正截面混凝土极限压应变epsilon_cu&#…

IP网络广播系统有哪些优点

IP网络广播系统有哪些优点 IP网络广播系统有哪些优点&#xff1f; IP网络广播系统是基于 TCP/IP 协议的公共广播系统&#xff0c;采用 IP 局域网或 广域网作为数据传输平台&#xff0c;扩展了公共广播系统的应用范围。随着局域网络和 网络的发展 , 使网络广播的普及变为可能 …

透过康希诺,谈谈疫苗这个行业

这两天疫苗企业的财报陆续发布了&#xff0c;国外的辉瑞和默沙东&#xff0c;国内像康希诺、智飞生物这些&#xff0c;8月30日&#xff0c;康希诺公布2023年半年报&#xff1a;实现总收入2590.78万元&#xff0c;归母净利润亏损8.41亿元&#xff0c;主要系由于新冠疫苗产品需求…