【问题标题】:Why is peewee including the 'id' column into the mysql select query?为什么 peewee 在 mysql 选择查询中包含“id”列?
【发布时间】:2013-03-11 16:01:35
【问题描述】:

我正在尝试学习如何在 mysql 中使用 peewee。

我在 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 列。我只是想使用现有的表,而不是依赖 peewee 每次我想与数据库交互时都必须创建一个。这就是我认为错误所在。

查询的结果应该是空的,因为表是空的,但是因为我正在学习,所以我只是想尝试一下代码。感谢您的帮助。

编辑

基于 Wooble 和 Francis 的有益回复,我开始怀疑使用 peewee 或其他 ORM(如 sqlalchemy)对我来说是否有意义。使用 ORM 而不是只使用 MySQLdb 在 python 中运行直接查询有什么好处?

这是我期望做的:

-自动从各种网络服务器下载数据。大多数数据是 xls 或 csv 格式。我可以使用 xlrd 包将 xls 转换为 csv。

-在插入/批量插入 mysql 数据库表之前解析/处理列表对象中的数据。

-运行复杂的查询以将数据从 mysql 导出到 python 到适当的数据结构(例如列表)中,用于各种统计计算,这在 python 中而不是 mysql 中更容易完成。可以在 mysql 中完成的任何事情都将在那里完成,但我可能会在 python 中运行复杂的回归。

-对从查询中检索到的数据运行各种图形包。其中一些可能包括使用 ggplot2 包(来自 R-project),这是一个高级图形包。所以我将涉及一些 R/Python 集成。

鉴于上述情况 - 我最好花几个小时学习 ORM/Peewee/SQLAlchemy 还是坚持使用 MySQLdb 直接查询 mysql?

【问题讨论】:

    标签: python mysql select create-table peewee


    【解决方案1】:

    大多数简单的活动记录模式 ORM 需要一个 id 列来跟踪对象身份。 PeeWee 似乎是其中之一(或者至少我不知道有任何方式使用 id)。如果不更改表格,您可能无法使用 PeeWee。

    无论如何,您现有的表似乎设计得不是很好,因为它似乎缺少键或复合键。每个表都应该有一个关键属性——否则就不可能区分一行。

    如果这些列之一是主键,请尝试按照 in the docs concerning non-integer primary keys 的说明添加 primary_key=True 参数

    date = DateField(primary_key=True)
    

    如果您的主键未命名为 id,那么您必须在该表的 peewee 模型中将表的实际主键设置为“PrimaryKeyField()”类型。

    您应该调查使用数据映射器模式的SQLAlchemy。它更复杂,但也更强大。它对你的 SQL 表设计没有任何限制,事实上它在大多数情况下可以自动反映你的表结构和相互关系。 (在 MySQL 中可能不太好,因为外键关系在默认表引擎中不可见。)对您来说最重要的是,它可以处理缺少键的表。

    【讨论】:

    • 感谢您的详细回复。事实证明,数据库中的现有表确实有一个主键(日期)。我是否需要按照 Wooble 的指示使用 pwiz 向 peewee 提供此信息?感谢您的帮助。
    • 您不必需要--pwiz 只是一个代码生成器,不会做任何您自己做不到的事情。可能只包含primary_key=True 参数,如in the docs describing non-integer primary keys 所述。
    • 我正在调查 SQLAlchemy,因为 peewee 将来不会做我想做的事。
    • 很抱歉听到 peewee 没有做您需要的事情 - 如果您能提供任何建议或我可以做的事情来改进它,我将不胜感激。
    • 这对我有用,如果您是数据库新手,也不要将 primary_key 混淆为唯一键。
    【解决方案2】:

    您必须为此模型提供 primary_key 字段。 如果您的表没有单个 primary_key 字段(就像我的一样),在 Meta 中定义的 CompositeKey 会有所帮助。

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

    【讨论】:

    • 我已经更新了答案,现在很清楚了。刚刚找到了一种制作 CompositeKey 的方法。
    【解决方案3】:

    如果您的主键列名称不是“id”,则应向该表模型类添加其他字段:

    class Table(BaseModel):
        id_field = PrimaryKeyField()
    

    这将告诉您的脚本,您的表的主键存储在名为“id_field”的列中,并且该列是启用了自动增量的 INT 类型。 Here 是描述 peewee 中字段类型的文档。

    如果您想对主键字段进行更多控制,正如 Francis Avila 已经指出的那样,您应该在创建字段时使用 primary_key=True 参数:

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

    在非整数主键文档中查看 this link

    【讨论】:

      【解决方案4】:

      在调用select()之前,需要使用peewee的create table方法创建实际的数据库表,这将在表中创建一个id列。

      【讨论】:

      • 会在我的实际数据库中创建表吗?我已经在数据库中有该表。我很困惑,因为 peewee 文档对新手不太友好。
      • 另外 - 是否有分步指南/示例说明如何执行以下操作:a)连接到数据库,b)将存储在列表对象中的记录插入表中,c)执行复杂的查询(使用连接、分组等),以及 d)将查询结果存储在 python 列表对象中,然后可用于其他目的。 peewee 文档没有正确解释包的最终用例以及如何完成我描述的从 a 到 d 的工作流程。
      • peewee.readthedocs.org/en/latest/peewee/example.htmlEvery model has a create_table() classmethod which runs a CREATE TABLE statement in the database. It will create the table, including all columns, foreign-key constaints, and indexes. Usually this is something you’ll only do once, whenever a new model is added.。这个包如何不能与现有表一起使用?我错过了什么吗?感谢您的帮助。
      • 查看peewee.readthedocs.org/en/latest/peewee/… -- 您需要使用pwiz 实用程序为遗留数据库生成模型;默认用法是定义模型并让框架处理数据库端。
      • 感谢您的 Wooble!我会看看。但是,如果您对此有任何指导,我对我的原始帖子进行了编辑,并提出了一个后续问题。我很感激。谢谢。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-04-01
      • 1970-01-01
      • 1970-01-01
      • 2020-10-05
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      相关资源
      最近更新 更多