psycopg2 - 尝试将数据插入postgres表时for循环问题 - eval()arg 1必须是字符串或代码对象

时间:2015-01-05 23:29:27

标签: python postgresql python-2.7 psycopg2

我已经结束了这个问题。

所以我创建了一个从操作系统捕获数据的脚本,将其插入到字典中。下一步应该是将数据插入postgres数据库。但是,当执行循环数据的for循环时,我收到以下错误。

  

/usr/bin/python2.7   /home/gmastrokostas/PycharmProjects/learning/Violent_Python.py   Traceback(最近一次调用最后一次):文件   “/home/gmastrokostas/PycharmProjects/learning/Violent_Python.py”,行   52,在       for eval(server_info)中的db_loop:TypeError:eval()arg 1必须是字符串或代码对象

下面是postgres表脚本以及它自己的python脚本。表的名称是SERVERS,列是“hostname”,“OS”,“RAM”,“CPU”。

SQL SCRIPT创建表 - PostgreSQL 9.4

CREATE TABLE servers
(
  hostname character varying(50),
  "OS" character varying(25),
  "RAM" numeric(4,2),
  "CPU" character varying(50)
)
WITH (
  OIDS=FALSE
);
ALTER TABLE servers
  OWNER TO dbuser;

PYTHON SCRIPT

#!/usr/bin/python
import psutil
import os
import math
import platform
import subprocess
import socket
import psycopg2
from decimal import *

#Used by the convert values function.
factor = 1024

def Host_name():
    hostname = socket.gethostname()
    return hostname

def OS_make():
    #CPU INFORMATION.
    #cpu_version = platform.dist()[0]+" "+platform.dist()[1]
    cpu_version = platform.dist()[0]
    return  cpu_version

def Virtual_memory_usage():
    cvr_info = psutil.virtual_memory().total
    return round(cvr_info, 2)

def convert_values():
    cvr_info = Virtual_memory_usage()
    i = int(math.log(cvr_info)/math.log(factor))
    result = float(cvr_info)/factor**i
    return result

def get_processor_info():
    if platform.system() == "Windows":
        return platform.processor()
    elif platform.system() == "Darwin":
        return subprocess.check_output(['/usr/sbin/sysctl', "-n", "machdep.cpu.brand_string"]).strip()
    elif platform.system() == "Linux":
        command = "cat /proc/cpuinfo | grep 'model name' | head -1 | awk -F: '{print $2}'"
        return subprocess.check_output(command, shell=True).strip()
    return ""

#Adjusting precision and then appending to list information taken from Virtual_memory_usage function
mem_frmt =   "{0:.2f}".format(convert_values())

server_info = {'hostname': Host_name(), 'OS':OS_make(), 'RAM':mem_frmt, 'CPU':get_processor_info()}

conn = psycopg2.connect("host='10.0.0.41' dbname='serverinfo' user='dbuser'")
cur = conn.cursor()
for db_loop in eval(server_info):
  print db_loop #For testing
  cur.execute("""INSERT INTO servers(hostname,OS,RAM,CPU) VALUES('%s','%s','%s','%s')""" % \
        (db_loop['hostname'], db_loop['OS'], db_loop['RAM'], db_loop['CPU'])

  #FOR TESTING BUT IT DOES NOT WORK EITHER
  #cur.execute("""INSERT INTO servers(hostname) VALUES('%s')""" % \
  #      (db_loop['hostname'])
  )

conn.commit()

2 个答案:

答案 0 :(得分:0)

问题在于您正试图eval字典。 eval函数编译代码 - 即字符串。我不确定你在那里使用eval的意图是什么。

好消息是你不需要调用eval。更好的消息是,我根本不认为你需要一个循环。

您已构建要插入的命名数据的字典。您需要做的就是打开连接,获取光标并插入server_info数据,类似于您使用db_loop行所做的操作。

答案 1 :(得分:0)

您的代码中存在多个错误。首先,您要插入一行数据(server_info),这样您就不需要循环了。此外,对eval()的调用没有任何意义,因为该函数用于评估字符串中的Python代码,并且您将字典作为参数传递给它。

然后,您不应该自己引用SQL参数(例如,使用"%s"而不是"'%s'")。

最后,鉴于你已经在字典中有数据,使用它来为execute()方法提供绑定变量。

我会按如下方式编写代码:

server_info = {'hostname': Host_name(), 'OS':OS_make(), 'RAM':mem_frmt, 'CPU':get_processor_info()}

conn = psycopg2.connect("host='10.0.0.41' dbname='serverinfo' user='dbuser'")
curs = conn.cursor()

curs.execute("""INSERT INTO servers (hostname,OS,RAM,CPU) VALUES (%(hostname)s,%(OS)s,%(RAM)s,%(CPU)s)""", server_info)

conn.commit()