1

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!

1
  • I suppose that spaceCheck is actually None so you cannot ask for spaceCheck[counter]. Commented Sep 7, 2013 at 21:38

2 Answers 2

1

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()
Sign up to request clarification or add additional context in comments.

Comments

0

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!

2 Comments

Actually you are wrong. Passing integers as query parameteres is not a problem. Check out examples in documentation: docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.execute
I thought it seemed fishy, but it got it to work, so that's what I went with. Though you were right about indefinite loops.. I'll have to try your example, the only thing I'll have to add to it is adding up the counter. We have a table with so many open columns that player's names will go into so it can keep track of/save where in the game you are; though obviously if there's more than one person in a given room we don't want that one name being written over, hence the counter. It would move the fetchone() over to the next column. Thanks again for your help.. I know it's amateur hour in here.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.