python-3.x - sqlite3.OperationalError:无法打开数据库文件 - 一段时间后发生错误
问题描述
工具:
- 树莓派 3B
- 树莓派
- BME280
- Python3
- 烧瓶
- Sqlite3
错误代码:
Traceback (most recent call last):
File "BME280_DataCollector.py", line 65, in <module>
File "BME280_DataCollector.py", line 45, in logData
sqlite3.OperationalError: unable to open database file
在 Raspbian 上工作并希望将我的传感器数据存储在 sqlite3 数据库中。不知何故出现以下错误代码:“sqlite3.OperationalError:无法打开数据库文件”。
首先,我认为我请求数据库文件的速度太快,并将测量时间更改为分钟,但错误仍然可以重现。
我通过 df /tmp 查看了 /tmp。但是这个文件系统被 12% 使用并且没有过载。
此外,我尝试通过 chmod 为完整路径和数据库提供所有写入和读取权限,但也没有不同。另外,我放了代码的完整路径。
此外,我尝试了尝试和异常方法,但也没有什么成果。
不过,我想知道此故障是否发生在与数据库进行一定数量的交互时。我发现它总是在第 1020 次交互时停止。
我还尝试使用 shell 脚本重新启动 python 脚本,但由于缺乏经验和知识,它没有成功。
代码:
from flask import Flask,render_template,url_for,request,redirect, make_response, send_file
import random
import json
from time import sleep
from random import random
from flask import Flask, render_template, make_response
import datetime
import sqlite3
import sys
from matplotlib.backends.backend_agg import FigureCanvasAgg as FigureCanvas
from matplotlib.figure import Figure
import io
import os
import smbus2
import bme280
## FUNCTIONS ##
# get data
def getBMEdata():
port = 1
adress = 0x77
bus = smbus2.SMBus(port)
calibration_params = bme280.load_calibration_params(bus, adress)
bme_data = bme280.sample(bus, adress, calibration_params)
temp = '%.2f' % bme_data.temperature
hum = '%.2f' % bme_data.humidity
press = '%.2f' % bme_data.pressure
now = datetime.datetime.now() #get time
timeString = now.strftime('%d-%m-%Y %H:%M:%S') #write time to string
return temp, hum, press, timeString
# function to insert data on a table
def logData(temp, hum, press, timeString):
conn = sqlite3.connect(dbname)
curs = conn.cursor()
curs.execute("INSERT INTO BME280_data values((?), (?), (?), (?))", (timeString, temp, hum, press))
conn.commit()
conn.close()
# display data base
def displayData():
conn = sqlite3.connect(dbname)
curs = conn.cursor()
print("\nEntire database contents:\n")
for row in curs.execute("SELECT * FROM BME280_data"):
print(row)
conn.close()
## MAIN
if __name__ == '__main__':
count = 0
dbname = '/home/pi/projects/SmartPlanting/Sensors_Database/sensorsData.db'
sampleFreq = 60 #data collect every minute
while True:
temp, hum, press, timeString = getBMEdata() #get data
logData(temp, hum, press, timeString) #save data
sleep(sampleFreq) #wait
displayData() #show in terminal
#count = count+1
#print(count)
也许有人已经解决了这个问题,或者可以给我一个与烧瓶一起使用的 sqlite3 的替代品。
解决方案
建议:添加更完整的异常处理例程,因为您的堆栈跟踪可能更冗长。
但是从您的跟踪来看,有问题的第 45 行可能是这样的:(conn.commit()
或上面的行)。Python 已经在帮助您查明错误。函数 logData 有问题。
可能是您向表 BME280_data 提供了不正确的数据吗?要调试您的应用程序,我强烈建议您打印记录您尝试插入的数据(使用日志记录模块输出到文件和/或控制台)。我不知道您的表的结构,但您的某些字段可能具有与您尝试插入的数据不兼容的定义(数据类型)。您能够以可预测的方式重现问题这一事实非常有说服力,我的直觉是数据可能是原因。
总结一下:现在养成好习惯,至少添加基本的异常处理。高质量的应用程序应该具有异常处理和日志错误,以便人工审查和修复它们。这对于无人值守的应用程序更为重要,因为您不在控制台前,甚至可能没有机会看到发生的问题。
这是一个可能有帮助的教程:https ://code.tutsplus.com/tutorials/error-handling-logging-in-python--cms-27932
推荐阅读
- python - 从 Keras 检查点加载
- php - 如何检查在提交输入按钮时显示的哈希引脚并在未找到时显示未找到?
- java - 如何制作一个二维数组,其中下一行是Java中前一行的平方?
- python - 根据值将列表拆分为子列表
- c++ - C++ 用函数删除指针
- javascript - 使用事件监听器我们应该使用 useCapture 作为 false 来支持旧浏览器,否则它将被用作每个浏览器的默认值
- android - 如何在 MVVM 架构中使用协程进行改造
- reactjs - 使用 useEffect 调用 2 API 时 Redux 状态被覆盖
- java - 如何创建一个执行 TimerTasks 的守护进程?
- f# - 如何使用 Json.Net 将缺失的属性反序列化为 F# 记录中的空列表而不是 null