樹莓派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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM