我有一个需要一直运行的python脚本。有时它可以运行一天,有时它只运行一个小时。
import RPi.GPIO as GPIO
import fdb
import re
con = fdb.connect(dsn='10.100.2.213/3050:/home/trainee2/Desktop/sms', user='sysdba', password='trainee') #connect to database
cur = con.cursor() #initialize cursor
pinnen = [21,20,25,24,23,18,26,19,13,6,27,17] #these are the GPIO pins we use, they are the same on all PI's! We need them in this sequence.
status = [0] * 12 #this is an empty array were we'll safe the status of each pin
ids = []
controlepin = [2] * 12 #this array will be the same as the status array, only one step behind, we have this array so we can know where a difference is made so we can send it
GPIO.setmode(GPIO.BCM) #Initialize GPIO
getPersonIDs() #get the ids we need
for p in range(0,12):
GPIO.setup(pinnen[p],GPIO.IN) #setup all the pins to read out data
while True: #this will repeat endlessly
for e in range(0,12):
if ids[e]: #if there is a value in the ids (this is only neccesary for PI 3 when there are not enough users
status[e] = GPIO.input(pinnen[e]) #get the status of the GPIO. 0 is dark, 1 is light
if (status[e] != controlepin[e]): #if there are changes
id = ids[e]
if id != '': #if the id is not empty
if status[e] == 1: #if there is no cell phone present
cur.execute("INSERT INTO T_ENTRIES (F_US_ID, F_EN_STATE) values (? ,0)",(id)) #SEND 0, carefull! Status 0 sends 1, status 1 sends 0 to let it make sense in the database!!
else :
cur.execute("INSERT INTO T_ENTRIES (F_US_ID, F_EN_STATE) values (? ,1)",(id))
con.commit() #commit your query
controlepin[e] = status[e] #safe the changes so we woulnd't spam our database
time.sleep(1) #sleep for one second, otherwise script will crash cause of while true
def getPersonIDs(): #here we get the IDS
cur.execute("SELECT first 12 A.F_US_ID FROM T_RACK_SLOTS a order by F_RS_ID;") #here is where the code changes for each pi
for (ID) in cur:
ids.append(ID) #append all the ids to the array
该脚本用于手机架,通过LDR我可以看到手机是否存在,然后我将该数据发送到Firebird数据库。脚本正在运行我的Raspberry PI。
如果连接丢失几秒钟,脚本会停止吗?有没有办法确保他们的查询总是发送?
答案 0 :(得分:0)
如果连接丢失了几秒钟,脚本会停止吗?
更重要的是,脚本IS会针对每个Firebird命令停止,包括con.commit()
,并且只有当Firebird处理命令/查询时它才会继续。
所以,我不太了解Python库,我仍然会给你一些建议。
1)尽可能多地使用参数和prepared
查询。
if status[e] == 1: #if there is no cell phone present
cur.execute("INSERT INTO T_ENTRIES (F_US_ID, F_EN_STATE) values (? ,0)",(id)) #SEND 0, carefull! Status 0 sends 1, status 1 sends 0 to let it make sense in the database!!
else :
cur.execute("INSERT INTO T_ENTRIES (F_US_ID, F_EN_STATE) values (? ,1)",(id))
这不是最好的主意。您强制Firebird引擎解析查询文本并一次又一次地构建查询。浪费时间和资源。
正确的方法是进行INSERT INTO T_ENTRIES (F_US_ID, F_EN_STATE) values (?,?)
查询,然后进行prepare
查询,然后运行已准备好的查询来更改参数。你只需要在循环之前准备一次,然后多次运行它。
当然,我不知道如何在Python库中查询prepare
,但我认为你会找到这些例子。
2)不要使用SQL服务器来保存您获得的每个数据元素。这是一个众所周知的不良行为,十年前曾被提出过。特别是懒惰的版本引擎Interbase / Firebird就是。
问题是,Firebird每次发表声明都会检查一些内部统计数据,有时会决定做家务的时间。
例如,您的select
语句类似于garbage collection
。 Firebird可能会停止扫描所有表,找到孤立的过时版本的行并清除它们。例如,你的insert
语句类似于索引重新创建:如果Firebird认为索引的B-Tree过于片面,它会丢弃它,并构建一个新的平衡树,读出整个表(是的,阅读表格可能会在树木娱乐活动中引发GC。)
更重要的是,让我们远离Firebird的具体细节 - 你会做什么ig Firebird崩溃?只是崩溃,这是一个程序,就像每个程序一样,它可能有bug。或者例如,你的磁盘空间不足,Firebird就不能再在数据库中插入任何内容了 - 那么你的硬件传感器数据会在哪里结束?不知道它会丢失吗?
http://www.translate.ru - 这个通常比Google或Microsoft翻译好,特别是如果你将词汇表设置为计算机。
请参阅http://www.ibase.ru/dontdoit/上的#7 - "请勿在每一行"之后发出提交。在https://www.ibase.ru/45-ways-to-improve-firebird-performance-russian/处的#24建议提交大约一千行的数据包作为许多事务和过多未提交数据之间的最佳点。还要检查最后一个链接的#9,#10,#16和#17和#44。
我认为软件综合体的整体结构必须分为两种服务。
因此,例如,您将阈值设置为10240行。
flush
OS文件缓冲区,或者在可靠性和性能之间取得最佳平衡的东西。file handler
类型变量。这里的关键点是服务应该只进行最简单和最快速的操作。由于任何随机延迟都意味着您的实时生成的数据会丢失并且永远无法恢复。顺便说一句,如何在Python中禁用垃圾收集,因此它不会“停止世界”#34;突然?好的,半开玩笑。但问题仍然存在。 GC是系统的随机非确定性故障,与常规的非缓冲硬件数据采集非常兼容。使用大多数简单=可预测的服务可以更好地完成对非缓冲数据的主要采集,而GC是一个很好的全局优化,但价格往往会导致突然的本地无服务峰值。
因为这一切都发生在服务#1和另一个服务器上。
EXTERNAL TABLE
External Table
(从文件中分离firebird) ),然后重命名" Phone_1_Inserting"将文件导入" Phone_2_Done" (保持其更改状态)然后将其删除。总而言之,你应该解开你的服务。
https://en.wikipedia.org/wiki/Coupling_%28computer_programming%29
服务的主要责任在于准备好获取和保存数据流,而另一项服务的责任是将保存的数据转移到SQL数据库中以便于处理,并且它不是很大问题,如果它有时会延迟几秒钟,只要它最终不会丢失数据。