SQLAlchemy会生成自己的主键吗?

时间:2017-09-14 14:28:04

标签: python sqlalchemy vertica

我已经开始将SQLAlchemy集成到我的应用程序中,以使用 HP Vertica 数据库。
到目前为止,基本功能运行良好,但现在发生了一些非常奇怪的事情:

一个表有一个auto_increment“id”列 映射到此表的模型如下所示:

class MyModel(ModelBase):
    __tablename__ = "sometable"

    id = Column(Integer, primary_key=True)
    somefield = Column(Integer)
    otherfield = Column(Integer)

所以,我正在创建一个新的MyModel对象并将其添加到会话中,如下所示:

my_model = MyModel(
            somefield=...,
            otherfield=...
)
session.add(my_model)

没有传递“id”参数,因为它是auto_increment 致电session.commit()时,我收到了Vertica的错误:
无法插入或更新IDENTITY / AUTO_INCREMENT列“id”

我检查了异常以查看执行了哪些SQL语句,并且我看到一个随机值传递给“id”字段:

INSERT INTO "schemaname"."sometable" (id, somefield, otherfield) VALUES (3000001, 8781, 164)

我尝试过的事情并没有奏效:

  • 在模型中将autoincrement=True和/或default=None传递给id
  • 在创建新的id=None实例时显式传递MyModel - SQLAlchemy仍然传递了一个随机值......

备注:

  • 要使用SQLAlchemy和Vertica,我使用vertica_python驱动程序和sqlalchemy-vertica-python dialect,它是sqlalchemy的Postgres方言的继承者。我试图把这个错误归咎于方言,但我看了它的代码(它很小),它似乎根本不会影响这个。
  • SQLAlchemy version = 1.1.13
  • Python = 3.5

1 个答案:

答案 0 :(得分:1)

经过大量调试后,我设法找到了解决方案 问题是Vertica方言只是一个补丁,它继承了PostgreSQL方言的大部分行为。

因此,在插入新记录时,显然幕后发生的事情是发送nextval()查询以从 Vertica和Postgres 创建的内置序列中检索下一个ID用于自动递增(或串行)字段 因此,生成的ID实际上是在服务器端生成的 ,而PostgreSQL允许手动将值插入到串行字段中,而Vertica

解决方法:
我需要做的是创建ID字段INT,而不是auto_increment,然后手动创建一个序列,其名称就像自动生成的序列(现在已删除)。
类似的东西:

CREATE SEQUENCE sometable_id_seq START 1;

<强>更新
正如lv10所述,更简单的解决方法也可能是使用原始SQL查询而省略ID参数。