【问题标题】:SQL Alchemy NULL identity keySQLAlchemy NULL 身份密钥
【发布时间】:2023-03-28 01:53:01
【问题描述】:

我已经像这样定义了模型的表的 id 字段:

id = Column(Integer(15, unsigned=True),
               nullable=False,
               server_default='0',
               primary_key=True,
               unique=True,
               autoincrement=True)

并相应地更改了数据库(MySQL)表,但仍然在我创建模型时 并尝试提交它(我使用 SQLalchemy 0.7.8)

m = MyModel(values without defining the id)
session.add(m)
session.commit()

我收到此错误

FlushError: Instance <MyModel at 0x4566990> has a NULL identity key. 
If this is an auto-generated value, check that the database table 
allows generation of new primary key values, and that the mapped 
Column object is configured to expect these generated values.  Ensure 
also that this flush() is not occurring at an inappropriate time, such    
as within a load() event.

【问题讨论】:

  • 你能告诉我们你正在使用哪个数据库,你正在使用哪个版本的 sqlalchemy,以及结果对你很重要(即 pks 必须从 0 开始,或者你还好吗?从 1) 开始?
  • 我正在使用 SQLalchemy 0.7.8 和 MySQLdb。不,零并不重要。

标签: python mysql sqlalchemy flask-sqlalchemy


【解决方案1】:

我使用的是 Postgres 13,ID 的类型是 UUIT 数据类型。我遇到了同样的问题。 我已经通过应用 server_default 解决了它。

class TrafficLightController(Base):
    __tablename__ = 'Tlc'
    id = Column(UUID, primary_key=True, server_default='uuid_generate_v4()')
    type_id = Column('type_id', UUID)
    title = Column('title', String(100))
    gps_x = Column('gps_x', Float)
    gps_y = Column('gps_y', Float)
    hardware_config = Column('hardware_config', JSONB)
    lcu_id = Column('lcu_id', UUID)
    signal_id = Column('signal_id', UUID)

    def __init__(self, type_id, title, gps_x, gps_y, hardware_config, lcu_id, signal_id):
        self.type_id = type_id
        self.title = title
        self.gps_x = gps_x
        self.gps_y = gps_y
        self.hardware_config = hardware_config
        self.lcu_id = lcu_id
        self.signal_id = signal_id

if __name__ == "__main__":
    dbschema = 'asudd'
    engine = create_engine(DB_CONNECTION_STR, connect_args={'options': '-    csearch_path={}'.format(dbschema)})
    Session = sessionmaker(bind=engine)
    Base = declarative_base()
    Base.metadata.create_all(engine)

    session = Session()
    tlc_obj = TrafficLightController("b0322313-0995-40ac-889c-c65702e1841e", "test DK", 35, 45, "{}", None, None)
    session.add(tlc_obj)

【讨论】:

    【解决方案2】:

    我通过删除 server_default 值解决了这个问题

    【讨论】:

    • 我询问正在使用的数据库后端的原因是你会在使用 sqlite3 时遇到这个问题,但不会在使用 postgresql 时遇到这个问题。要完全摆脱这个问题,您可以简单地删除“server_default='0'”参数,它可以在任一数据库中工作。我的印象是,虽然 sqlite 支持自动递增主键没有问题,但它无法在刷新之前生成值并返回它们。另一件值得注意的事情是,在默认情况下,设置 primary_key=True 也会设置 autoincrement=True 和 nullable=False,因此您也可以删除它们。
    • 是的,你是对的!没有 server_default 也能完美运行
    • uniqueunsigned也没有必要。它只会让你的代码更复杂。我建议不要在那里设置长度限制,让数据库将 id 列作为默认整数处理。所以它可能只是:id = Column(Integer, primary_key=True).
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 2017-06-21
    • 2020-03-03
    相关资源
    最近更新 更多