当对基于声明的模型使用多值插入时,不会为每一行单独调用 Python 端默认值

Posted

技术标签:

【中文标题】当对基于声明的模型使用多值插入时,不会为每一行单独调用 Python 端默认值【英文标题】:Python-side defaults are not invoked for each row individually when using a multivalued insert for Declarative-based models 【发布时间】:2017-06-02 16:04:06 【问题描述】:

我正在使用sqlalchemy==1.1.4。我完全陷入了尝试为从DeclarativeMeta 类继承的模型执行多值insert 的问题。 我有下一个声明:

import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class SomeClass(Base):
    id = sa.Column(sa.String(length=64), primary_key=True,
               default=lambda: str(uuid4()))
    is_active = sa.Column(sa.Boolean, default=True)
    service_id = sa.Column(sa.String(length=100), nullable=False)
    order = sa.Column(sa.SmallInteger, default=0)

当我尝试多值插入时:

con.execute(
    sa.insert(SomeClass).values([
        SomeClass.service_id: '12',
        SomeClass.service_id: '34',
    ])
)

它抛出

sqlalchemy.exc.CompileError: INSERT value for column SomeClass.service_id is
  explicitly rendered as a boundparameter in the VALUES clause; a
  Python-side value or SQL expression is required

根据 Michael Bayer 的帖子link,无论如何我的代码似乎都是正确的,但它甚至没有编译为 sql 表达式。虽然下一个工作完美:

con.execute(
    sa.insert(SomeClass).values([
        SomeClass.service_id.key: '12',
        SomeClass.service_id.key: '34',
    ])
)

有人知道这是怎么回事吗?)

【问题讨论】:

这与默认值无关。 .values() 采用列 name 来为 dict 赋值。使用列表达式似乎适用于单行情况,但似乎没有记录。 是的,问题是每次提到 .values() 都记录在案,仅反映 column_name 用于多行的字符串格式,但没有关于传递 dicts 列表的信息Column 或 InstrumentedAttribute 之类的键 【参考方案1】:

只有当您传递给insert.values() 的元素列表包含不一致的键时,才会出现该错误,这意味着您可能有一个类似的列表:['name': 'foo', code:'foo', 'name': 'bar']

【讨论】:

以上是关于当对基于声明的模型使用多值插入时,不会为每一行单独调用 Python 端默认值的主要内容,如果未能解决你的问题,请参考以下文章

Mysql 触发器在循环前声明

MySQL假设基于多值插入和第一个ID的自动递增ID

将电子表格的行转换为单独的 XML 文件

Spring data solr 总是创建多值字段

R语言使用dplyr包基于因子变量(factor)将原dataframe拆分为每一个因子对应的单独数据集dataframe实战

如何插入 365 行并为每一行增加一天的日期