Почему peewee, включая столбец "id" в запросе select mysql?

Я пытаюсь научиться использовать peewee с mysql.

У меня есть существующая база данных на сервере mysql с существующей таблицей. В настоящее время таблица пуста (сейчас я просто тестирую).

>>> db = MySQLDatabase('nhl', user='root', passwd='blahblah')
>>> db.connect()


>>> class schedule(Model):
...     date = DateField()
...     team = CharField()
...     class Meta:
...             database = db

>>> test = schedule.select()
>>> test
<class '__main__.schedule'> SELECT t1.'id', t1.'date', t1.'team' FROM 'nhl' AS t1 []
>>> test.get()

Я получаю следующую ошибку:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python2.6/site-packages/peewee.py", line 1408, in get
    return clone.execute().next()
  File "/usr/lib/python2.6/site-packages/peewee.py", line 1437, in execute
    self._qr = QueryResultWrapper(self.model_class, self._execute(), query_meta)
  File "/usr/lib/python2.6/site-packages/peewee.py", line 1232, in _execute
    return self.database.execute_sql(sql, params, self.require_commit)
  File "/usr/lib/python2.6/site-packages/peewee.py", line 1602, in execute_sql
    res = cursor.execute(sql, params or ())
  File "/usr/lib64/python2.6/site-packages/MySQLdb/cursors.py", line 201, in execute
    self.errorhandler(self, exc, value)
  File "/usr/lib64/python2.6/site-packages/MySQLdb/connections.py", line 36, in defaulterrorhandler
    raise errorclass, errorvalue
_mysql_exceptions.OperationalError: (1054, "Unknown column 't1.id' in 'field list'")

Почему peewee добавляет столбец "id" в запрос выбора? У меня нет столбца id в таблице, которая уже существует в базе данных. Я просто хочу работать с существующей таблицей и не зависеть от того, должен ли она создавать ее каждый раз, когда я хочу взаимодействовать с базой данных. Здесь я верю, что ошибка.

Результат запроса должен быть пустым, поскольку таблица пуста, но поскольку я изучаю, я просто хотел попробовать код. Я ценю вашу помощь.

РЕДАКТИРОВАТЬ

Основываясь на полезных отзывах Wooble и Francis, я пришел к удивлению, имеет ли смысл иметь возможность использовать peewee или другой ORM, например sqlalchemy. Каковы преимущества использования ORM вместо того, чтобы просто запускать прямые запросы в python с помощью MySQLdb?

Это то, что я ожидаю делать:

-automatically загрузка данных с различных веб-серверов. Большая часть данных находится в формате xls или csv. Я могу преобразовать xls в csv, используя пакет xlrd.

-parsing/обработка данных в объектах списка перед вставкой/вставкой в таблицу mysql db.

-running сложные запросы для экспорта данных из mysql в python в соответствующие структурированные данные (например, списки) для различных статистических вычислений, которые проще делать в python вместо mysql. Все, что можно сделать в mysql, будет выполнено там, но я могу запустить сложные регрессии в python.

-run различные графические пакеты для данных, полученных из запросов. Некоторые из них могут включать использование пакета ggplot2 (из R-проекта), который представляет собой расширенный графический пакет. Поэтому я буду включать некоторую интеграцию R/Python.

Учитывая вышеизложенное - лучше ли мне тратить часы на взломы, чтобы изучить ORM/Peewee/SQLAlchemy или придерживаться прямых запросов mysql с помощью MySQLdb?

Ответ 1

Для большинства простых ORM шаблонов активной записи требуется id столбца для отслеживания идентификации объекта. PeeWee кажется одним из них (или, по крайней мере, я не знаю, каким образом не использовать идентификатор). Вероятно, вы не можете использовать PeeWee без изменения таблиц.

Ваша существующая таблица, похоже, не очень хорошо спроектирована, так как ей не хватает ключа или сложного ключа. Каждая таблица должна иметь ключевой атрибут, иначе невозможно отличить одну строку от другой.

Если один из этих столбцов является первичным ключом, попробуйте добавить параметр primary_key=True как описано в документах относительно нецелых первичных ключей

date = DateField(primary_key=True)

Обратите внимание, что я не уверен, что PeeWee будет расстроен тем, что первичный ключ не назван id.

Вы должны исследовать SQLAlchemy, который использует шаблон data-mapper. Это намного сложнее, но и намного более мощным. Он не устанавливает никаких ограничений на ваш дизайн таблицы SQL, и на самом деле он может автоматически отражать структуру вашей таблицы и взаимосвязи в большинстве случаев. (Возможно, не так, как в MySQL, так как отношения внешнего ключа не видны в машинном модуле по умолчанию.) Самое главное для вас, он может обрабатывать таблицы, которым не хватает ключа.

Ответ 2

Если имя вашего основного ключевого столбца отличается от "id", вы должны добавить дополнительное поле к этому классу модели таблицы:

class Table(BaseModel):
    id_field = PrimaryKeyField()

Это скажет вашему скрипту, что ваша таблица имеет первичные ключи, хранящиеся в столбце с именем "id_field", и этот столбец является типом INT с включенным автоматическим добавлением. Вот документация, описывающая типы полей в peewee.

Если вы хотите больше контролировать поле первичного ключа, как уже указывал Фрэнсис Авила, вы должны использовать primary_key = True аргумент при создании поля:

class Table(BaseModel):
    id_field = CharField(primary_key=True)

См. Эту ссылку в документации по нецелым первичным ключам

Ответ 3

Вы должны указать для этой модели поле primary_key. Если в вашей таблице нет ни одного поля primary_key (точно так же, как у меня), то поможет CompositeKey, определенный в Meta.

primary_key = peewee.CompositeKey('date', 'team')

Ответ 4

Вам нужно, чтобы мы создали метод таблицы, чтобы создать фактическую таблицу базы данных, прежде чем вы сможете вызвать select(), который создаст столбец идентификатора в таблице.