Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 每秒向MySQL表插入数据(每秒一次)_Python_Mysql_Raspberry Pi_Raspberry Pi2 - Fatal编程技术网

Python 每秒向MySQL表插入数据(每秒一次)

Python 每秒向MySQL表插入数据(每秒一次),python,mysql,raspberry-pi,raspberry-pi2,Python,Mysql,Raspberry Pi,Raspberry Pi2,我是Python、Raspberry Pi和MySQL的新手,希望您能帮助我。我正在尝试用Python编写一个脚本,它可以每秒将数据插入MySQL表。我可以插入数据,但不是我想要的周期性数据,我已经尝试了很多,但我找不到解决问题的方法。下面是我的Python代码和插入MySQL表的数据: Python代码: 表格结果: 如您所见,有时纸条会周期性地插入数据,有时数据之间有8秒的间隔。所以,我的问题是:每次数据之间的间隔是否可能是1秒?我做错了什么? 抱歉英语不好,提前谢谢 不要为此使用事务,当尝

我是Python、Raspberry Pi和MySQL的新手,希望您能帮助我。我正在尝试用Python编写一个脚本,它可以每秒将数据插入MySQL表。我可以插入数据,但不是我想要的周期性数据,我已经尝试了很多,但我找不到解决问题的方法。下面是我的Python代码和插入MySQL表的数据:

Python代码: 表格结果: 如您所见,有时纸条会周期性地插入数据,有时数据之间有8秒的间隔。所以,我的问题是:每次数据之间的间隔是否可能是1秒?我做错了什么?
抱歉英语不好,提前谢谢

不要为此使用事务,当尝试插入新行时,可能某些表被锁定。

您在每次迭代中都要建立到数据库服务器的新连接。这可能需要任意的时间。将
.connect()
等移动到循环之外可能会使计时更加一致:

db = MySQLdb.connect("localhost", "mauro", "12345", "temps")
curs = db.cursor()

while True:    
    try:
        curs.execute ("""INSERT INTO thetemps 
                values(0, CURRENT_DATE(), NOW(), 28)""")
        db.commit()
        print "Data committed"
    except:
        print "Error"
        db.rollback()    
    time.sleep(1)
db.close()

尝试在之前创建与db的连接,同时保持连接的打开状态。

我看到的问题是连接+插入需要时间,这将累积起来,您的进程最终将落后

我要做的是将数据收集(确保每秒读取一次温度)与数据加载分开(如果需要,数据加载可能需要一秒钟以上的时间,但不会落后)

所以,如果我是你,我会有两个独立的脚本并行运行,并通过一些简单、快速和可靠的机制进行通信。在中列出一个列表可能会很有用。你也可以用类似的东西

大概是这样的:

# gather.py
while True:
    temp = get_temp()
    redis.lpush('temps', pickle.dumps([temp, datetime.now]))
    time.sleep(1)

您可以在上面添加一些改进,比如重用db连接、确保在出现db错误时不会丢失TEMP、为数据点使用namedtuple而不是数组等

每次数据之间的间隔是否可能为1秒

理论上是的,但实际上有太多其他因素超出了你的控制范围,更可能成为阻碍。其中包括但不限于:

  • 操作系统内核的任务调度器
  • 与其他任务相关的任务优先级
  • 系统总负荷
  • 表中已有的数据量(检查二叉树的时间复杂度)
  • 这意味着,即使您的系统大部分时间处于空闲状态,
    time.sleep(1)
    也不能保证总是睡眠1秒钟,即使如此,系统也可能一直在做其他事情(例如,更多的I/O),每次都需要不同的时间来执行相同的操作

    此外,不要每次在循环中创建新连接,而应该保持连接打开并节省开销

    我做错了什么

    我不认为你在这里做错了什么。代码看起来没问题,除了每次创建新连接的额外开销之外,您不应该这样做。除此之外,这里的问题归结为您无法控制的因素

    也就是说,你可以做一些事情来提高你的机会


    提高性能的一些附加建议 存储引擎 除了避免每次迭代时打开/关闭数据库连接的开销外,还应该检查用于表的存储引擎。例如,根据您的MySQL版本,默认值可能仍然是
    MyISAM
    ,这需要表锁定才能写入

    相反,
    InnoDB
    在写入表时只需要行锁定,如果其他人正在使用表,这应该会有所改善。如果发现没有使用
    InnoDB
    ,请发出
    alter table…
    查询以更改存储引擎

    自动提交而不是事务 事务意味着将一组2个或多个查询作为单个单元进行分组,但您提交的是单个查询。相反,您应该将MySQL配置为启用自动提交,以便在提交和执行查询后,它不必等待显式的
    commit
    请求,从而节省服务器和客户端之间的一些通信开销

    通过增加优先级来影响操作系统调度程序 您可以为您的程序设置更高的优先级,以使调度程序在此处更有帮助。它还可能有助于对数据库服务/进程执行相同的操作


    如有必要,其他用户级任务的优先级也可以降低一点。

    .connect
    .close
    放在while循环之外,这样就不需要每次都重新初始化。这并不能保证任何事情,但它可能更加一致。您可以做的另一件事是不使用
    时间。sleep
    您可以读取表中的最后一个时间值,然后在这之后的第二秒执行您的命令,以确定发生了什么,您需要对python进程和mysqld进行扫描(使用-tt获取时间戳)。如果您只是想猜测,除了已经说过的内容,如果表是InnoDB,请更改表thetemps ENGINE=MYISAM。Raspberry PI可能没有足够的umph来有效地处理InnoDB表。事务提交可能需要一段时间。请不要忘记返回并接受您认为对您最有用的答案。这对你、那些试图解决你的问题的人以及整个社区的其他人都有好处。谢谢@SashaPachev!!这使我的脚本工作,因为我想+1对于这个想法,尽管我认为实现^^与OP有相同的问题:
    connect()
    ,等等。可能需要任意的时间,时间戳(
    NOW()
    )的差异可能超过1s。@eugeney是的,我重新阅读了代码,出现了一系列错误。试图修复它们,尽管它更像是一个通用id
    db = MySQLdb.connect("localhost", "mauro", "12345", "temps")
    curs = db.cursor()
    
    while True:    
        try:
            curs.execute ("""INSERT INTO thetemps 
                    values(0, CURRENT_DATE(), NOW(), 28)""")
            db.commit()
            print "Data committed"
        except:
            print "Error"
            db.rollback()    
        time.sleep(1)
    db.close()
    
    # gather.py
    while True:
        temp = get_temp()
        redis.lpush('temps', pickle.dumps([temp, datetime.now]))
        time.sleep(1)
    
    # load.py
    while True:
        # Block until new temps are available in redis
        data, key = redis.brpop('temps')
        # Get all temps queued
        datapoints = [data] +  redis.rpop('temps'):
        db = MySQLdb.connect("localhost", "mauro", "12345", "temps")
        curs=db.cursor()
        try:
            for p in datapoints:
                point = pickle.loads(p)
                curs.execute ("INSERT INTO thetemps (temp, timestamp) values({}, {})".format(point[0], point[1])
            db.commit()
            print "Data committed"
        except:
            print "Error"
            db.rollback()