mathieu
mathieu

Reputation: 107

Python sqlite3 NoneType error

We're working on a text-based game (MUD) and have hit this roadblock.

The code:

class RoomMove():

    def __init__(self):
        self.room = 1
        self.name = 'Lorinth'
        self.moveRooms()
        self.updateRoom()

[extra code doesn't matter]

def updateRoom(self):
        global c
        room = str(self.room)
        room = (room)
        print room
        while room > 0:
            c.execute("""SELECT * FROM RoomPlayers where ID=?""", room)
            spaceCheck = c.fetchone()
            print spaceCheck
            counter = 1
            if spaceCheck[counter] not in ('', None):
                counter += 1
            else:
                room = self.room
                name = self.name
                c.execute("""UPDATE RoomPlayers SET '1'=? WHERE ID=?""", (name, room))
        conn.commit()

it throws back this error:

     c.execute("""SELECT * FROM RoomPlayers where ID=?""", room)
ValueError: parameters are of unsupported type

EDITS: I've tried it with (room, ) ..no difference in the error though.

Any ideas?

Thanks!

Upvotes: 1

Views: 2412

Answers (2)

mathieu
mathieu

Reputation: 107

What fixed the problem shown above:

sqlite3 doesn't read integers, just strings. (not actually true)

So I made the integer be read as a string in the else loop.

here:

else:
        room = self.room
        name = self.name
        c.execute("""UPDATE RoomPlayers SET '1'=? WHERE ID=?""", (name, room))

room is being passed to c.execute as an integer, the solution?

else:
    room = str(self.room)
....

Took forever to see that!

Upvotes: 0

zero323
zero323

Reputation: 330163

As you can read in the documentation:

fetchone()

Fetches the next row of a query result set, returning a single sequence, or None when no more data is available.

If there is no more data c.fetchone() assigns None to the spaceCheck variable, hence TypeError when you try to access spaceCheck[counter].

Try something like that:

        if spaceCheck is not None:
            counter += 1

UPDATE

You should replace

room = (room)

with:

room = (room, )

Another update

Assuming you create table like below:

sqlite> CREATE TABLE RoomPlayers (ID numeric, player_name VARCHAR);

Your code could like similar to this:

class RoomMove():

    def __init__(self, room, name):
        self.room = room
        self.name = name
        self.con = None
        self.db_path = "./foo.sqlite"

    def updateRoom(self):
        try:
            # Globals are evil. Don't use them 
            self.con = sqlite3.connect(self.db_path)
            c = con.cursor()
            # comparing tuple or string to number dosen't make sense. Compare original number
            # You should check if room is valid inside constructor
            #  while room > 0 would probably lead to indefinite loop
            if rooom > 0:
                #You don't have to cast room number to string
                c.execute("""SELECT id FROM RoomPlayers where ID=?""", (self.room, ))
                spaceCheck = c.fetchone()

                # Your counter takes only two values so you can do it like that
                counter = 2 if spaceCheck is not None else 1

                if counter == 1:
                    # Don't name columns '1' - it is really bad idea
                    # Like above - coneverting room and name to string is pointlees
                    c.execute("""UPDATE RoomPlayers SET 'player_name'=? WHERE ID=?""", (self.name, self.room))
                    self.con.commit()

        finally:
            # No matter what happens close connection
            if self.con is not None:
                self.con.close()

Upvotes: 1

Related Questions