简体   繁体   中英

Python will not pull values from dictionary properly using for loop

Im trying to use a dictionary to check a given number of servers listed for a particular SQL backup success or fail. My problem so far is when I run this code:

for serverChk in srvrDict['Server']:

it returns the server name as single characters on each new line like:
S
E
R
V
E
R
So in my trial I see this "Error connecting to T to check OS version" where T is the fist character of the servername. I can't seem to put my finger on it and all the searching I've done has lead me to asking. Thanks!

class checkstatus:
#def getServers(self):
    chkbkpstats = csv.reader(file('c://temp//networkerservers.csv'))
    for row in chkbkpstats:
        srvrDict = {}
        srvrDict['Server'] = row[0]
        srvrDict['Instance'] = row[1]
        print srvrDict

for serverChk in srvrDict['Server']:
        try:
            c = wmi.WMI(server)
            for os in c.Win32_OperatingSystem():
                osVer = os.caption
        except:                 
            print 'Error connecting to %s to check OS version' % serverChk

        if '2003' in osVer:
            print 'w2k3'
        if '2008' in osVer:
            print 'w2k8'

I suppose you have stored a string in your dictionary. So the line for serverChk in srvrDict['Server'] translates to for serverChk in yourSavedString . This is why you are getting individual characters. To access individual dictionary items you should do for k,v in srvrDict.iteritems() where k is the key and v is the value.

You are overwriting the Server and Instance values in srvrDict each iteration of your loop through chkbkpstats , not actually generating a sequence of data with an entry for each item in your log file as it appears you expect. You need to make that a list containing dictionaries, which you append to each iteration. You are probably looking for something more like:

chkbkpstats = csv.reader(file('c://temp//networkerservers.csv'))
srvrs = []
for for row in chkbkpstats:
    srvrs.append({'Name' : row[0], 'Instance' : row[1]})
for srvr in srvrs:
    try:
        c = wmi.WMI(srvr['Instance'])
    except:                 
        print 'Error connecting to %s to check OS version' % srvr['Name']
    else:
        osVer = c.Win32_OperatingSystem()[0].Caption
        if '2003' in osVer:
            print 'w2k3'
        elif '2008' in osVer:
            print 'w2k8'

There are a few problems with your code.

First, you create a new srvrDict each time you go through the first for loop, overwriting the value that was stored in this variable the last time. I think, what you actually intended to do is the following:

srvrDict = {}
for row in chkbkpstats:
    srvrDict[row[0]] = row[1]

Now, srvrDict will contain an entry like {'P1RT04': ['THP06ASU']} for each row in chkbkpstats , mapping server names to lists of instances running on that server.

Then, in the second loop, use for serverChk in srvrDict: to iterate over all the entries in the dictionary. However, I'm not sure where the variable server in c = wmi.WMI(server) comes from. If this is what has been row[1] in the first loop, then you should use srcvDict[serverChk] to retrieve the value from the dictionary.

This way, the whole procedure would look something like this:

chkbkpstats = csv.reader(file('c://temp//networkerservers.csv'))
srvrDict = {}
for row in chkbkpstats:
    name, instance = row[0], row[1]
    if name not in srvrDict:
        srvrDict[name] = []
    srvrDict[name].append(instance)

for server in srvrDict:
    for instance in srvrDict[server]:
        try:
            c = wmi.WMI(instance)
        except:                 
            print 'Error connecting to %s to check OS version' % server
        else:
            osVer = c.Win32_OperatingSystem()[0].caption
            if '2003' in osVer:
                print 'w2k3'
            elif '2008' in osVer:
                print 'w2k8'
            else:
                print 'unknown OS'

PS.: I'm not sure what's the return value of c.Win32_OperatingSystem() . [...] Update: Thanks to sr2222 for pointing this out. Code fixed.

Update: Edited the code to allow for one server hosting multiple instances.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM