2013-09-07 2 views
0

Мы работаем над текстовой игрой (MUD) и попали в этот блокпост.Python sqlite3 NoneType error

Код:

class RoomMove(): 

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

[дополнительный код не имеет значения]

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() 

он откидывает эту ошибку:

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

правок: Я пытался это с (комната,) ..но разница в ошибке, хотя.

Любые идеи?

Спасибо!

+0

Я полагаю, что spaceCheck фактически отсутствует, поэтому вы не можете запросить spaceCheck [counter]. – zero323

ответ

1

Как вы можете прочитать в documentation:

fetchone()

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

Если нет более c.fetchone данных() не присваивает None переменной spaceCheck, следовательно TypeError при попытке получить доступ к spaceCheck [счетчик].

попробовать что-то вроде этого:

 if spaceCheck is not None: 
      counter += 1 

UPDATE

Вы должны заменить

room = (room) 

с:

room = (room,) 

Очередное обновление

Предполагая, что вы создаете таблицу, как показано ниже:

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

Ваш код может нравится похожее на это:

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() 
0

Что констатировала проблема показано выше:

sqlite3 Безразлично 't читать целые числа, просто строки. (на самом деле это не так)

Таким образом, я сделал целое число считанным как строка в цикле else.

здесь:

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

номер передается в c.execute как целое, решение?

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

Взял навсегда, чтобы увидеть это!

+0

На самом деле вы ошибаетесь. Передача целых чисел в качестве параметров запроса не является проблемой.Ознакомьтесь с примерами в документации: http://docs.python.org/2/library/sqlite3.html#sqlite3.Cursor.execute – zero323

+0

Я думал, что это показалось мне подозрительным, но это заставило его работать, так что я и пошел. Хотя вы были правы в неопределенных циклах. Я должен попробовать ваш пример, единственное, что мне нужно добавить, это добавить счетчик. У нас есть таблица с таким количеством открытых столбцов, в которые войдут имена игроков, чтобы они могли отслеживать/сохранять, где находятся в вашей игре; хотя, очевидно, если в данной комнате больше одного человека, мы не хотим, чтобы одно имя было написано, следовательно, счетчик. Он переместит fetchone() в следующий столбец. Еще раз спасибо за вашу помощь. Я знаю, что здесь час любителя. – mathieu