【问题标题】:null value for primary key when trying to insert list of dictionaries尝试插入字典列表时主键的空值
【发布时间】:2019-11-29 05:30:01
【问题描述】:

我正在尝试一次调用大量插入,这里有人推荐的方法是给.insert 一个字典列表。这是使用 SQLAlchemy Core。

举个例子:

    try:
        engine = db.create_engine(f"postgres://user:pass@myip/addressbook", connect_args={'connect_timeout': 5})
        connection = engine.connect()
        metadata = db.MetaData()
    except exc.OperationalError:
        print_error(f":: Could not connect to myip!")
        sys.exit()

    table_addressbook = db.Table('addressbook', metadata, autoload=True, autoload_with=engine)

    list = []
    list.append({'firstname': "John", 'lastname': "Doe"})
    list.append({'firstname': "Jane", 'lastname': "Doe"})

    query = db.insert(table_addressbook).values(list)
    connection.execute(query)

但我收到一条错误消息,指出 id 列违反了非空约束。这是因为插入通常会自动生成主键id。如何使用此方法但指定应自动生成 id?或者我应该使用其他方法吗?

编辑

表名是addressbook

idinteger 类型,默认sequence 'untitled_table_id_seq',约束是PRIMARY_KEY。这是由 Postico for Mac 自动生成的,但我一直能够在不包含 id 的情况下插入,并且它会从最后插入的 ID 自动递增。

firstnamelastnametext 类型,没有默认值,没有约束。

【问题讨论】:

  • 检查address_book表声明并为id列添加uuid自动生成
  • 我很困惑。它在任何其他示例中都会自动生成。此外,其他帖子中关于 uuid 自动生成的详细信息讨论了将系统的 MAC 地址与其他内容结合使用,但我所说的 ID 每次都会增加..
  • @Max,你能提供你是如何创建模型和连接代码的吗?

标签: python sqlalchemy


【解决方案1】:

如果没有关于您的型号和/或连接的任何信息,回答您的问题有点困难。请在下面找到一段使用insert 而不会引发非空约束错误的代码。希望对您有所帮助。

from sqlalchemy import create_engine, Column, Integer, String, Table
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
from sqlalchemy.sql import insert

engine = create_engine('sqlite:///:memory:', echo=True)

Base = declarative_base()

class User(Base):
    __tablename__ = 'users'
    id = Column(Integer, primary_key=True)
    firstname = Column(String)
    lastname = Column(String)

Base.metadata.create_all(engine)

Session = sessionmaker(bind=engine)
Session.configure(bind=engine)  # once engine is available
session = Session()

new_users = []
new_users.append({'firstname': "John", 'lastname': "Doe"})
new_users.append({'firstname': "Jane", 'lastname': "Doe"})

i = insert(User).values(new_users)
session.execute(i)

PS:大部分内容来自以下教程:https://docs.sqlalchemy.org/en/13/orm/tutorial.html

【讨论】:

  • 我忘了说我正在使用 SQLAlchemy Core。我现在将我的代码贴在上面。
  • 啊,这确实帮助我结合了我在代码中发现的错误。谢谢!
  • 太好了,很高兴我能帮上忙!
【解决方案2】:
from sqlalchemy import Column
from sqlalchemy import create_engine
from sqlalchemy import Integer
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import Session

engine = create_engine('sqlite:///:memory:', echo=True)

Base = declarative_base()

# Example Model definition for the illustration
class Customer(Base):
    __tablename__ = "customer"
    id = Column(Integer, primary_key=True)
    name = Column(String(255))
    description = Column(String(255))

Base.metadata.create_all(engine)

######################################################
# Bulk insert using dictionaries.
######################################################
# Insert test records into `customer`table.

def bulk_insert_customers(n):
    session = Session(bind=engine)
    session.bulk_insert_mappings(
        Customer,
        [
            dict(
                name="customer name %d" % i,
                description="customer description %d" % i,
            )
            for i in range(n)
        ],
    )
    session.commit()

有关如何以不同方式进行批量插入的更多示例,请参阅以下内容: https://docs.sqlalchemy.org/en/13/_modules/examples/performance/bulk_inserts.html

【讨论】:

  • 我正在使用 SQLAlchemy 核心,抱歉,之前忘记提及了。用完整的代码和表格信息更新了我的帖子。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-09-23
  • 2020-12-28
  • 1970-01-01
  • 2019-01-28
相关资源
最近更新 更多