在Python中使用ConfigParser - 测试正常但在部署后擦除文件

时间:2017-02-15 02:22:35

标签: python configparser

我正在运行自己的池控制系统,我想实现将某些系统参数复制到平面文件,以便通过我正在处理的Web界面进行处理。由于只有几个条目我喜欢ConfigParser的工作。

我构建了一个测试设置,效果很好。这是代码:

import ConfigParser

config = ConfigParser.ConfigParser()
get_pool_level_resistance_value = 870


def read_system_status_values(file, section, system):
    config.read(file)
    current_status = config.get(section, system)
    print("Our current {} is {}.".format(system, current_status))


def update_system_status_values(file, section, system, value):
    cfgfile = open(file, 'w')
    config.set(section, system, value)
    config.write(cfgfile)
    cfgfile.close()
    print("{} updated to {}".format(system, value))


def read_test():
    read_system_status_values("current_system_status", "system_status",
                              "pool_level_resistance_value")


def write_test():
    update_system_status_values("current_system_status", "system_status",
                                "pool_level_resistance_value",
                                get_pool_level_resistance_value)


read_test()
write_test()
read_test()

这是我的配置文件" current_system_status":

[system_status]
running_status = True
fill_control_manual_disable = False
pump_running = True
pump_watts = 865
pool_level_resistance_value = 680
pool_level = MIDWAY
pool_is_filling = False
pool_is_filling_auto = False
pool_is_filling_manual = False
pool_current_temp = 61
pool_current_ph = 7.2
pool_current_orp = 400
sprinklers_running = False
pool_level_sensor_battery_voltage = 3.2
pool_temp_sensor_battery_voltage = 3.2
pool_level_sensor_time_delta = 32
pool_temp_sensor_time_delta = 18

当我运行我的测试文件时,我得到了这个输出:

ssh://root@scruffy:22/usr/bin/python -u /root/pool_control/V3.2/system_status.py
Our current pool_level_resistance_value is 350.
pool_level_resistance_value updated to 870
Our current pool_level_resistance_value is 870.

Process finished with exit code 0

这完全符合预期。但是,当我将它移动到我的主pool_sensors.py模块时,无论何时运行它我都会收到以下错误:

Traceback (most recent call last):
  File "/root/pool_control/V3.2/pool_sensors.py", line 58, in update_system_status_values
    config.set(section, system, value)
  File "/usr/lib/python2.7/ConfigParser.py", line 396, in set
    raise NoSectionError(section)
ConfigParser.NoSectionError: No section: 'system_status'

Process finished with exit code 1

然后我调试了(使用PyCharm),当我在代码中到达这一行时,我正在浏览代码:

cfgfile = open(file, 'w')

它彻底清除了我的文件,因此我得到了NoSectionError。当我调试我的测试文件并且它到达完全相同的代码行时,它会打开文件并按预期更新它。

测试文件和实际文件都使用相同版本的所有内容位于同一台计算机上的同一目录中。打开和写入文件的代码与测试代码完全相同,但" production"中的调试打印语句除外。码。

我尝试了各种方法,包括:

cfgfile = open(file, 'w')
cfgfile = open(file, 'r')
cfgfile = open(file, 'wb')

但无论我使用哪一个,一旦我将测试代码包含在我的生产文件中,一旦它到达该行,它就会完全消除文件,而不是像我的测试文件一样更新它。

以下是我称之为代码的pertenent行:

import pooldb  # Database information
import mysql.connector
from mysql.connector import errorcode
import time
import notifications
import logging
import ConfigParser

DEBUG = pooldb.DEBUG
config = ConfigParser.ConfigParser()

def read_system_status_values(file, section, system):
    config.read(file)
    current_status = config.get(section, system)
    if DEBUG:
        print("Our current {} is {}.".format(system, current_status))


def update_system_status_values(file, section, system, value):
    cfgfile = open(file, 'w')
    config.set(section, system, value)
    config.write(cfgfile)
    cfgfile.close()
    if DEBUG:
        print("{} updated to {}".format(system,value))

def get_pool_level_resistance():
    """ Function to get the current level of our pool from our MySQL DB. """
    global get_pool_level
    try:
        cnx = mysql.connector.connect(user=pooldb.username,
                                      password=pooldb.password,
                                      host=pooldb.servername,
                                      database=pooldb.emoncms_db)
    except mysql.connector.Error as err:
        if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:
            logger.error(
                'Database connection failure: Check your username and password')
            if DEBUG:
                print(
                    "Database connection failure: Check your username and "
                    "password")
        elif err.errno == errorcode.ER_BAD_DB_ERROR:
            logger.error('Database does not exist. Please check your settings.')
            if DEBUG:
                print("Database does not exist. Please check your settings.")
        else:
            logger.error(
                'Unknown database error, please check all of your settings.')
            if DEBUG:
                print(
                    "Unknown database error, please check all of your "
                    "settings.")
    else:
        cursor = cnx.cursor(buffered=True)
        cursor.execute(("SELECT data FROM `%s` ORDER by time DESC LIMIT 1") % (
            pooldb.pool_resistance_table))

        for data in cursor:
            get_pool_level_resistance_value = int("%1.0f" % data)
            cursor.close()
            logger.info("Pool Resistance is: %s",
                        get_pool_level_resistance_value)
            if DEBUG:
                print(
                    "pool_sensors: Pool Resistance is: %s " %
                    get_pool_level_resistance_value)
                print(
                    "pooldb: Static critical pool level resistance set at ("
                    "%s)." %
                    pooldb.pool_resistance_critical_level)
                print(
                    "pooldb: Static normal pool level resistance set at (%s)." %
                    pooldb.pool_resistance_ok_level)
        cnx.close()

    print("We made it here with a resistance of (%s)" %
          get_pool_level_resistance_value)
    update_system_status_values("current_system_status",
                                "system_status",
                                "pool_level_resistance_value",
                                get_pool_level_resistance_value)

    if get_pool_level_resistance_value >= pooldb.pool_resistance_critical_level:
        get_pool_level = "LOW"
        update_system_status_values("current_system_status",
                                    "system_status",
                                    "pool_level",
                                    get_pool_level)
        if DEBUG:
            print("get_pool_level_resistance() returned pool_level = LOW")
    else:
        if get_pool_level_resistance_value <= pooldb.pool_resistance_ok_level:
            get_pool_level = "OK"
            update_system_status_values("current_system_status",
                                        "system_status",
                                        "pool_level",
                                        get_pool_level)
            if DEBUG:
                print("get_pool_level_resistance() returned pool_level = OK")

    if DEBUG:
        print("Our Pool Level is %s." % get_pool_level)

    return get_pool_level

我怀疑它可能与另一个导入有关,可能与open(文件,&#39; w&#39;)冲突。

我的主要模块是pool_fill_control.py,它有这些导入:

import pooldb  # Configuration information
import datetime
import logging
import os
import socket
import subprocess
import threading
import time
import RPi.GPIO as GPIO  # Import GPIO Library
import mysql.connector
import requests
import serial
from mysql.connector import errorcode
import notifications
import pool_sensors
import ConfigParser

在该模块的一个函数中,它使用以下代码行调用上面显示的pool_sensors.py模块:

get_pool_level = pool_sensors.get_pool_level_resistance()

任何关于它为什么单向工作而不是另一种方式的信息或帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

嗯,有趣的是在做了更多的研究并逐行查看代码后,我意识到我在测试文件中唯一不同的是在写入之前先读取我的文件。

所以我改变了我的代码如下:

旧代码:

def update_system_status_values(file, section, system, value):
    cfgfile = open(file, 'w')
    config.set(section, system, value)
    config.write(cfgfile)
    cfgfile.close()
    if DEBUG:
        print("{} updated to {}".format(system,value))

新密码(感谢@ShadowRanger)

def update_system_status_values(file, section, system, value):
    config.read(file)
    cfgfile = open('tempfile', 'w')
    config.set(section, system, value)
    config.write(cfgfile)
    cfgfile.close()
    os.rename('tempfile', file)
    if DEBUG:
        print("{} updated to {}".format(system, value))

现在它就像一个魅力!!

现在是以下步骤:

1)阅读

2)打开临时文件

3)更新它

4)写临时文件

5)关闭临时文件

6)在主文件上重命名临时文件