树莓派 python mysql_树莓派ZeroW的Python中使用SQLite数据库

本文介绍了如何在树莓派ZeroW上使用Python与SQLite数据库进行交互,主要用于存储通讯数据。通过创建数据库、记录表,以及插入数据的函数,实现了将通讯原始数据按时间戳存储的功能。示例代码展示了如何初始化SQL语句、创建记录集合,并进行批量插入。
摘要由CSDN通过智能技术生成

SQLite数据库(www.sqlite.org)是一个轻型的数据库引擎,应用非常广泛。我们使用SQLite来存储采集到的通讯数据,一帧通讯原始数据加上时间戳后作为一条记录存入数据库中。在这个项目中,只需要用到数据库的存储功能,不需要查询之类的(到本地上位机上解析数据时才会用到),所以下面也只介绍存储相关的部分,其他功能可以参考这个网址:

程序说明

用下面这些函数就可以插入记录完成存储,还需要解决的是SQL语句:sql_create_table、sql_insert_record,以及记录集合:records_list。

1 import sqlite3

2

3 # 连接到SQLite数据库:DB_NAME,如果不存在就创建

4 conn = sqlite3.connect(DB_NAME)

5 # 创建一个游标Cursor,可以通过Cursor来执行SQL语句

6 cursor = conn.cursor()

7 # 创建记录表:records

8 cursor.execute(sql_create_table)

9 # 插入多条记录

10 cursor.executemany(sql_insert_record, records_list)

11 # 关闭Cursor

12 cursor.close()

13 # 提交事务

14 conn.commit()

15 # 关闭数据库连接

16 conn.close()

>> SQL语句:sql_create_table、sql_insert_record

sql_create_table

在数据库中建一个表records,表中记录的结构为:单条记录结构:id(自增),时间戳(text),从数据库创建开始的累计时间(real),通讯原始数据(400个,int)

sql_insert_record

插入记录时只需要:时间戳、累计时间、通讯数据*400

1 def init_sql_sentences(param_num):

2 global sql_create_table

3 global sql_insert_record

4

5 # sql_create_table

6 sql_create_table = 'create table if not exists records('

7 sql_create_table += 'id integer primary key autoincrement, '

8 sql_create_table += 'datetime text, '

9 sql_create_table += 'runningtime real, '

10 for i in range(0, param_num - 1):

11 sql_create_table += 'param' + str(i) + ' int, '

12 sql_create_table += 'param' + str(param_num - 1) + ' int)'

13

14 # sql_insert_record

15 sql_insert_record = 'insert into records values (null, ?, ?, '

16 for i in range(0, param_num - 1):

17 sql_insert_record += '?, '

18 sql_insert_record += '?)'

>> 记录集合:records_list

按照记录的格式,将时间戳、通讯数据等存入单条记录record_buff[],然后再把record_buff[]添加到到记录集records_list[],这里使用了tuple,把record_buff[]转换成元组,这样就负荷cursor.executemany()函数要求的格式了。

1 records_list = []

2 record_buff = []

3 record_buff.append('')

4 record_buff.append(0.0)

5 for i in range(0, DB_PARAMS_LENGTH):

6 record_buff.append(0)

7

8 ####

9 record_buff[0] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())

10 record_buff[1] = round((time.time() - start_time), 1)

11 for i in range(0, DB_PARAMS_LENGTH):

12 record_buff[i + 2] = comn_data[i]

13 comn_data[i] = 0

14 records_list.append(tuple(record_buff[:]))

创建测试文件test_sqlite.py

用模拟通讯数据,生成100条记录,插入数据库,等待0.4s。循环10次以后退出。

pi@raspberrypi:~ $ sudo nano test_sqlite.py

1 # -*- coding:utf-8 -*-

2 import time

3 import sqlite3

4 import os

5 from datetime import datetime

6

7 DEFAULT_DIR = '/home/pi/project/'

8 DB_DIR = '/home/pi/project/data/'

9 DB_TMP_DIR = '/home/pi/project/data/tmp/'

10 DB_UPDATING_DIR = '/home/pi/project/data/updating/'

11 DB_UPDATED_DIR = '/home/pi/project/data/updated/'

12

13 DB_NAME = ''

14

15 PRODUCT_TYPE = 'NULL'

16 DEVICE_ID = 999

17 DB_PARAMS_LENGTH = 400

18

19 sql_create_table = ''

20 sql_insert_record = ''

21

22 def init_sql_sentences(param_num):

23 ####

24

25 def main():

26 global PRODUCT_TYPE

27 global DEVICE_ID

28 global DB_PARAMS_LENGTH

29

30 record_count = 0

31 insert_count = 0

32

33 record_buff = []

34 records_list = []

35 comn_data = [0 for i in range(DB_PARAMS_LENGTH)]

36

37 record_buff.append('')

38 record_buff.append(0.0)

39 for i in range(0, DB_PARAMS_LENGTH):

40 record_buff.append(0)

41

42 if not os.path.exists(DEFAULT_DIR):

43 os.mkdir(DEFAULT_DIR)

44 if not os.path.exists(DB_DIR):

45 os.mkdir(DB_DIR)

46 if not os.path.exists(DB_TMP_DIR):

47 os.mkdir(DB_TMP_DIR)

48 if not os.path.exists(DB_UPDATING_DIR):

49 os.mkdir(DB_UPDATING_DIR)

50 if not os.path.exists(DB_UPDATED_DIR):

51 os.mkdir(DB_UPDATED_DIR)

52

53 init_sql_sentences(DB_PARAMS_LENGTH)

54

55 DB_NAME = DB_TMP_DIR+PRODUCT_TYPE + '_' + str(DEVICE_ID).rjust(3,'0') + '_' \

56 + time.strftime('%Y-%m-%d_%H%M%S', time.localtime()) + '.db3'

57

58 print('>> sqlite test start...')

59 print(DB_NAME)

60

61 start_time = time.time()

62 while insert_count < 10:

63 # set fake data

64 for i in range(0, DB_PARAMS_LENGTH):

65 comn_data[i] = i

66 comn_data[0] = record_count

67

68 record_buff[0] = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())

69 record_buff[1] = round((time.time() - start_time), 1)

70 for i in range(0, DB_PARAMS_LENGTH):

71 record_buff[i + 2] = comn_data[i]

72 comn_data[i] = 0

73

74 records_list.append(tuple(record_buff[:]))

75 record_count = record_count + 1

76

77 if((record_count % 100) == 0):

78 conn = sqlite3.connect(DB_NAME)

79 cursor = conn.cursor()

80 cursor.execute(sql_create_table)

81 cursor.executemany(sql_insert_record, records_list)

82 cursor.close()

83 conn.commit()

84 conn.close()

85

86 records_list = []

87 records_need_save = False

88

89 print('>> sqlite insert records: ' + \

90 str(insert_count * 100) + ' - ' + str(insert_count * 100 + 99))

91 insert_count = insert_count + 1

92 time.sleep(0.4)

93

94 print('>> sqlite test finish...')

95

96 if __name__ == '__main__':

97 main()运行结果

运行test_sqlite.py,显示总共插入10次(每次有100条记录)

pi@raspberrypi:~ $ python test_sqlite.py

156778880b137fffce40465f54080b80.png

查看数据库是否存在,显示新生成一个数据库:NULL_999_2020-04-23_160903.db3

pi@raspberrypi:~ $ cd /home/pi/project/data/tmp/

pi@raspberrypi:~/project/data/tmp $ ls -lh

1366bd67d17361943c0fe2613439a908.png

在同一无线网络系啊,使用FileZilla软件登陆树莓派,把数据库文件从树莓派中拷贝到电脑上。

主机:raspberrypi.local,用户名:pi,密码:raspberry,端口:22,点击 快速连接

99d73acd716a780dd639792227269dac.png

远程站点中,进入/home/pi/project/data/tmp目录

995ce777169c7f494e71f0ec44cffe0e.png

将下面的数据库文件复制到本地站点的一个目录下(双击或者拖拽都可以):

d0dc36e273153ca5df9a2c04428e996a.png

用SQLite Expert打开这个文件,点击records表,可以看到里面的数据:

723fcaa0360897395bd8f4f5c7330168.png

扩展内容:存储逻辑

>> 存储位置

创建3个文件夹:文件夹、文件夹、文件夹临时新收到通讯数据时,在该文件夹下建立数据库,持续写入数据;

持续写入1小时/持续1分钟未收到新数据,关闭该数据库,移动至;

上电后首先将该目录下的数据库文件移动至

待上传数据上传服务程序每隔30s扫描一次该目录

如果有文件,则开始上传第1个文件,上传完成后将该文件移动至

如果采集装置离线,则该目录为实际存储目录

已上传如果采集装置在线,则该目录为实际存储目录

>> 批量写入

为了提高写入效率,可以把记录先放在内存里,攒够N条记录(100条)后再一次性写入到数据库中。当然如果较长的一段时间(10s)没有收到新的数据帧,就会认为被监听的设备掉线,这时把已经有的记录写入到数据库中。

>> 定时打包

连续采集较长时间(1个小时),或者连续一段时间(≥1分钟)没有收到新的数据帧,就结束往当前数据库写入记录,相当于把这段时间的数据打包成一个数据库,便于后续使用。把这个数据库移动到待上传的文件夹中,然后再新建一个数据库继续采集。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值