zoukankan      html  css  js  c++  java
  • 树莓派ZeroW上传数据文件到阿里云对象存储OSS(Python)

    >> [目录] 数据远程采集 Step by Step


    树莓派型号:Zero W

    树莓派系统:Raspbian,2018-11-13-raspbian-stretch-lite.img

    SD卡:闪迪32G class10 高速Micro SD卡(TF卡)

    存储工具:阿里云->对象存储



    阿里云的SDK文档(有各种语言的版本,这里选的是Python),提供了上传数据的样例程序:

    https://help.aliyun.com/document_detail/32027.html?spm=a2c4g.11186623.2.24.5c741c62a5XKqp#concept-32027-zh

    # -*- coding: utf-8 -*-
    import oss2
    
    # 阿里云主账号AccessKey拥有所有API的访问权限,风险很高。强烈建议您创建并使用RAM账号进行API访问或日常运维,请登录 https://ram.console.aliyun.com 创建RAM账号。
    auth = oss2.Auth('<yourAccessKeyId>', '<yourAccessKeySecret>')
    # Endpoint以杭州为例,其它Region请按实际情况填写。
    bucket = oss2.Bucket(auth, 'http://oss-cn-hangzhou.aliyuncs.com', '<yourBucketName>')
    
    # <yourObjectName>上传文件到OSS时需要指定包含文件后缀在内的完整路径,例如abc/efg/123.jpg。
    # <yourLocalFile>由本地文件路径加文件名包括后缀组成,例如/users/local/myfile.txt。
    bucket.put_object_from_file('<yourObjectName>', '<yourLocalFile>')
    


    功能需求


    间隔一段时间扫描一次<待上传>目录,如果该目录下有数据文件,就将第一个文件上传到对象存储指定bucket(考虑到以后会有几十台数据采集装置,为了便于管理,每个装置在bucket上有一个专属的二级子目录),上传成功后将这个文件移动到<已上传>目录下。


    环境准备


    手动创建两个工作目录,分别用于存放<待上传>和<已上传>的数据文件:

    mkdir -p ~/project/data/updating

    mkdir -p ~/project/data/updated


    updating目录下用touch指令创建一个测试文件test.db:

    pi@raspberrypi:~ $ cd ~/project/data/updating

    pi@raspberrypi:~/project/data/updating $ touch test.db

    image


    程序文件


    切换到主目录下,创建test_upload.py文件,复制内容进去,保存退出

    注意:<yourAccessKeyId>、<yourAccessKeySecret>、<yourBucketName>要改成自己的

    pi@raspberrypi:~/project/data/updating $ cd ~

    pi@raspberrypi:~ $ sudo nano test_upload.py

      1 # -*- coding: utf-8 -*-
      2 import os
      3 import time
      4 import shutil
      5 import oss2
      6 import ConfigParser
      7 
      8 PRODUCT_TYPE = 'NULL'
      9 DEVICE_ID = 999 #default
     10 
     11 #----
     12 def UploadFile_oss2(localfile):
     13   global PRODUCT_TYPE
     14   global DEVICE_ID
     15 
     16   access_key = '<yourAccessKeyId>'
     17   secret_key = '<yourAccessKeySecret>'
     18 
     19   try:
     20     auth = oss2.Auth(access_key, secret_key)
     21     bucket = oss2.Bucket(auth, 'oss-cn-beijing.aliyuncs.com', '<yourBucketName>')
     22 
     23     # 文件是否存在
     24     print '>> uploading local file: ' + localfile
     25     if False == os.path.exists(localfile):
     26       print '>> local file not exist: ' + localfile
     27       return False
     28 
     29     # 根据产品类型、树莓派编号,生成二级目录
     30     objectname = PRODUCT_TYPE + '_' + str(DEVICE_ID).rjust(3,'0') 
     31                  + '/' + os.path.basename(localfile)
     32     print '>> upload result...'
     33     result = bucket.put_object_from_file(objectname, localfile)
     34 
     35     print result
     36 
     37     # result.status 200 表示上传成功
     38     if result.status == 200:
     39       return True
     40     else:
     41       return False
     42   except:
     43     return False
     44 
     45 #----
     46 def UploadFile(localfile):
     47   return UploadFile_oss2(localfile)
     48 
     49 #----
     50 def main():
     51   global PRODUCT_TYPE
     52   global DEVICE_ID
     53 
     54   DB_UPDATING_DIR = '/home/pi/project/data/updating/'
     55   DB_UPDATED_DIR  = '/home/pi/project/data/updated/'
     56   CONFIG_FILE     = '/home/pi/project/config.ini'
     57   file_path       = ''
     58 
     59   # time.sleep(10)
     60   # 读取产品类型、树莓派编号
     61   GetDeviceInfo(CONFIG_FILE)
     62 
     63   print '>> uploading scheduler start...'
     64   while True:
     65     filelist = os.listdir(DB_UPDATING_DIR)
     66     if len(filelist) > 0:
     67       # 获得<待上传>文件夹下的第一个数据文件
     68       file_path = os.path.join(DB_UPDATING_DIR, filelist[0])
     69       if os.path.exists(file_path):
     70         print '>> file need upload: ' + file_path
     71         if True == UploadFile(file_path):
     72           # 上传成功,将数据文件放到<已上传>文件夹中
     73           MoveFile(file_path, DB_UPDATED_DIR)
     74           print '>> upload succeed: '+ file_path
     75 
     76     # 每隔一段时间扫描一次<待上传>文件夹(每小时生成一个新的数据文件)
     77     time.sleep(30)
     78 
     79 #----
     80 def GetDeviceInfo(file_path):
     81   global PRODUCT_TYPE
     82   global DEVICE_ID
     83 
     84   # 读取配置信息
     85   PRODUCT_TYPE = 'NULL'
     86   DEVICE_ID = 999
     87   '''
     88   try:
     89     config = ConfigParser.ConfigParser()
     90     config.read(file_path)
     91     if "device" in config.sections():
     92       PRODUCT_TYPE = config.get("device", "type")
     93       DEVICE_ID    = config.getint("device", "id")
     94   except:
     95     # 配置文件加载异常,使用默认参数:产品类型NULL 树莓派编号999
     96     PRODUCT_TYPE = 'NULL'
     97     DEVICE_ID = 999
     98   '''
     99 
    100 #----
    101 def MoveFile(src_file_path, dst_folder_path):
    102   try:
    103     if not os.path.exists(dst_folder_path):
    104       os.mkdir(dst_folder_path)
    105     shutil.move(src_file_path, dst_folder_path)
    106   except:
    107     return
    108 
    109 #----
    110 if __name__ == '__main__':
    111   main()


    >> def UploadFile_oss2(localfile):

    这个函数把本地文件上传到阿里云对象存储的buckek空间。

    基本是按照官方提供的样例程序写的,加了一些防止异常的冗余代码。

    上传时使用二次子目录,直接在objectname加上目录就可以了

    objectname = 'NULL_999/' + os.path.basename(localfile)

    上传结果result.status为200表示上传成功。


    >> def UploadFile(localfile):

    调用UploadFile_oss2,隔离一下,万一要改成其他云。


    >> def GetDeviceInfo(file_path):

    获取设备信息:产品信号、设备编号,每个设备根据这个信息,可以在bucket空间上创建专属的二级子目录,便于管理数据。

    这些设置信息保存在一个配置文件中,用ConfigParser库进行访问,为了简化操作现在这段代码暂时注释掉了,直接使用默认的设备信息。


    >> def MoveFile(src_file_path, dst_folder_path):

    文件上传成功后,从<待上传>移动到<已上传>。

    如果目标目录不存在,使用os库创建该目录;使用shutil库进行文件移动操作。


    >> def main():

    间隔一段时间扫描一次<待上传>目录,上传该目录下的第一个文件。

    filelist = os.listdir(DB_UPDATING_DIR),获得该目录下的文件清单

    os.path.join(DB_UPDATING_DIR, filelist[0]),获得第一个文件的路径


    运行测试


    运行test_upload.py,显示数据上传成功

    pi@raspberrypi:~ $ python test_upload.py

    image

    切换到updated目录下,文件已经移动过来了

    pi@raspberrypi:~ $ cd ~/project/data/updated

    pi@raspberrypi:~/project/data/updated $ ls

    image

    打开阿里云app,管控->文件管理->xxxx_bucket_name,多了一个NULL_999的二级目录,进入该目录,test.db文件已经上传成功了。

    image

  • 相关阅读:
    2019春招面试题总结-03
    2019春招面试题总结-02
    2019春招面试题总结-01
    Node.js 全局对象
    Node.js 路由
    Node.js 函数
    Node.js 模块系统
    Node.js Stream(流)
    Node.js Buffer(缓冲区)
    Node.js EventEmitter
  • 原文地址:https://www.cnblogs.com/hotwater99/p/12751818.html
Copyright © 2011-2022 走看看