简体   繁体   中英

sqlite query in python writes only last row to file using objects

First off... I'm new to Python in the last couple of months and up till now it's been going pretty well. But I'm stumped here and I'm very close to smashing my head through my monitor.

When I run this script I only get the last line of data written to a file while what I need is all lines of data to be written in the format that is in the class section.

VOL_HOURS.db has at multiple rows but only the last one being written. Here is my script:

    from vlist import VLIST

import sqlite3
import decimal
import os
import sys
import uuid

VERSION = "oops"
DEVICE_SOFTWARE_VERSION = "OOPS"
FILENAME = "VHOURS.txt"
conn = sqlite3.connect("VOL_HOURS.db")






def fromVolunteers():
    conn = sqlite3.connect("VOL_HOURS.db")


with conn:

    cur = conn.cursor()
    cur.execute("SELECT BOB, DAVE, CAROL, ANDY, CARL, DANNY, CHERYL, CYNTHIA, TARA, SCOTT, ASHLEY, CRYSTAL FROM VOLUNTEERS")
    rows = cur.fetchall()




for row in rows:
    bob = row[0] 
    dave = row[1]
    carol = row[2]
    andy= row[3]
    carl = row[4]
    danny = row [5]
    cheryl = row [6]
    cynthia = row [7]
    tara = row [8]
    scott = row [9]
    ashley = row [10]
    crystal = row [11]



def main():
    fromVolunteers()
    testOutput = open(FILENAME, "w+")

    vlist = VLIST()
    vlist.setBob(bob)
    vlist.setDave(dave)
    vlist.setCarol(carol)
    vlist.setAndy(andy)
    vlist.setCarl(carl)
    vlist.setDanny(danny)
    vlist.setCheryl(cheryl)
    vlist.setCynthia(cynthia)
    vlist.setTara(tara)
    vlist.setScott(scott)
    vlist.setAshley(ashley)
    vlist.setCrystal(crystal)

    vlist.dump_object(testOutput)

    testOutput.flush()
    testOutput.close()
cur.close()
conn.close()

if __name__ == "__main__":
    sys.exit(main())

The class file that it's pulling from is:

class VLIST:

    def __init__(self):
        self.bob = ""
        self.dave = ""
        self.carol = ""
        self.andy = ""
        self.carl = ""
        self.danny = ""
        self.cheryl = ""
        self.cynthia = ""
        self.tara = ""
        self.scott = ""
        self.ashley = ""
        self.crystal = ""

    def setBob(self,bob):
        self.bob = bob
        return

    def setDave(self,dave):
        self.dave = dave
        return

    def setCarol(self,carol):
        self.carol = carol
        return

    def setAndy(self,andy):
        self.andy = andy
        return

    def setCarl(self,carl):
        self.carl = carl
        return

    def setDanny(self,danny):
        self.danny = danny
        return

    def setCheryl(self,cheryl):
        self.cheryl = cheryl
        return

    def setCynthia(self,cynthia):
        self.cynthia = cynthia
        return

    def setTara(self,tara):
        self.tara = tara
        return

    def setScott(self,scott):
        self.scott = scott
        return

    def setAshley(self,ashley):
        self.ashley = ashley
        return

    def setCrystal(self,crystal):
        self.crystal = crystal
        return

    def dump_object(self,testOutput):
        testOutput.write("VLIST,"+self.bob+","+self.dave+","+self.carol+","+self.andy+","+self.carl+","+self.danny+","+self.cheryl+","+self.cynthia+","+self.tara+","+self.scott+","+self.ashley+","+self.crystal+","+"\n")

I apologize in advance if this is confusing, like I said I'm new to this whole this. Thank you for your time.

Inside the iteration for row in rows: you are just overwritting the previous value of the variables bob , dave , etc. Thus, at the end of the iteration, those variables has the only the last value.

Remove the iteration from fromVolunteers() . This function should only set the rows variable, and put the iteration in the main function:

import sqlite3
import decimal
import os
import sys
import uuid

VERSION = "oops"
DEVICE_SOFTWARE_VERSION = "OOPS"
FILENAME = "VHOURS.txt"
conn = sqlite3.connect("VOL_HOURS.db")

def fromVolunteers():
    conn = sqlite3.connect("VOL_HOURS.db")

    with conn:
        cur = conn.cursor()
        cur.execute("SELECT BOB, DAVE, CAROL, ANDY, CARL, DANNY, CHERYL, CYNTHIA, TARA, SCOTT, ASHLEY, CRYSTAL FROM VOLUNTEERS")
        rows = cur.fetchall()
def main():
    fromVolunteers()
    testOutput = open(FILENAME, "w+")

    for row in rows:
        vlist = VLIST()
        vlist.setBob(row[0])
        vlist.setDave(row[1])
        vlist.setCarol(row[2])
        vlist.setAndy(row[3])
        vlist.setCarl(row[4])
        vlist.setDanny(row[5])
        vlist.setCheryl(row[6])
        vlist.setCynthia(row[7])
        vlist.setTara(row[8])
        vlist.setScott(row[9])
        vlist.setAshley(row[10])
        vlist.setCrystal(row[11])
        vlist.dump_object(testOutput)

testOutput.flush()
testOutput.close()
cur.close()
conn.close()

Here is a refactored version of your code. Without knowing you database schema, what it contains, or having an example file to test with, this is just an approximation of what you could be doing instead. As your VOLUNTEERS table continues to have columns added or removed, you should only need to change the COLUMNS tuple at the top of the code to compensate for the change.

import contextlib
import sqlite3


DATABASE = 'VOL_HOURS.db'
OUTPUT = 'VHOURS.nmf'
COLUMNS = ('BOB', 'DAVE', 'CAROL', 'ANDY', 'CARL', 'DANNY', 'CHERYL',
           'CYNTHIA', 'TARA', 'SCOTT', 'ASHLEY', 'CRYSTAL')


def main():
    with open(OUTPUT, 'w') as file:
        for row in from_volunteers():
            file.write(str(VolunteerList.new(row)))


def from_volunteers():
    with sqlite3.connect(DATABASE) as connection:
        with contextlib.closing(connection.cursor()) as cursor:
            query = 'SELECT {} FROM VOLUNTEERS'.format(', '.join(COLUMNS))
            cursor.execute(query)
            return cursor.fetchall()


class VolunteerList:

    @classmethod
    def new(cls, row):
        obj = cls()
        for key, value in zip(COLUMNS, row):
            obj[key] = value
        return obj

    def __init__(self):
        self.__data = [''] * len(COLUMNS)

    def __setitem__(self, key, value):
        self.__data[COLUMNS.index(key.upper())] = value

    def __str__(self):
        return ','.join(['VLIST'] + self.__data + ['\n'])


if __name__ == '__main__':
    main()

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