簡體   English   中英

sqlalchemy:如何在 mysql 中添加具有自動增量的表行

[英]sqlalchemy: how to add a table row with autoincrement in mysql

我在 mysql 5.5 中使用 sqlalchemy 0.8

我有一個簡單的表,其 ORM 定義如下所示

class TrackingTable(db.Model):

    __tablename__ = 'tracking_table'

    trackid = db.Column(db.BigInteger,primary_key=True)
    custid = db.Column(db.String(20), db.ForeignKey('customer.id'))
    tracktime = db.Column(db.DateTime ,nullable=False)
    formdata = db.Column(db.String(100),nullable=False)

我假設(根據文檔) trackid 是 BIGINT 類型的主鍵,因此它會自動遞增。

但是當我嘗試在 db 中添加一條記錄時

updateRecord = TrackingTable(custid='002',tracktime='2013-02-02',formdata='logged in')

db_session.add(updateRecord)
db_session.flush()
db_session.commit()

它發出警告警告:字段“trackid”沒有默認值

並且 trackid 的值始終為 0,因此第二次添加始終失敗,錯誤為 IntegrityError: (IntegrityError) (1062, "Duplicate entry '0' for key 'PRIMARY'") 'INSERT INTO tracking_table (custid, tracktime , 表格數據)

請幫我解決這個問題。 理想情況下,我希望這是一個由數據庫處理的遞增值,但我無法弄清楚如何實現這一點。

提前致謝

最相似的原因是數據庫中有一個名為tracking_table的現有表,該表定義了主鍵列,默認值為零但沒有設置autoincrement ,如下所示(省略了某些列):

CREATE TABLE `tracking_table` (
  `trackid` int(11) NOT NULL DEFAULT 0,
  `formdata` varchar(100) DEFAULT NULL,
  PRIMARY KEY (`trackid`)
)

因為表已經存在 SQLAlchemy 不會嘗試創建它。 一旦表包含trackid為零的單行,嘗試寫入表將觸發觀察到的異常。

至少有兩種方法可以解決問題:

  • 在 trackid 列上設置自動增量; 如果表中沒有行,或者trackid為零的trackid ,這將起作用

    ALTER TABLE tracking_table MODIFY COLUMN trackid int(11) auto_increment

    如果已經有行,那就更復雜了

    ALTER TABLE tracking_table DROP CONSTRAINT PRIMARY KEY; ALTER TABLE tracking_table ADD COLUMN id int(11) primary key auto_increment; ALTER TABLE tracking_table DROP COLUMN trackid; ALTER TABLE tracking_table CHANGE COLUMN id trackid int(11) auto_increment;

    如果有外鍵關系,那就更棘手了。

  • 刪除表並重新創建它,無論是在數據庫中還是使用 SQLALchemy 的元數據方法。 同樣,外鍵關系會使問題復雜化。

您需要將字段值設置為“AUTO_INCREMENT”,而不是將實際值傳遞給它,而是傳遞 NULL。 首先嘗試傳遞 NULL,因為它可能已經設置為 AUTO_INCREMENT。

無法重現,在這里工作正常:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class TrackingTable(Base):

    __tablename__ = 'tracking_table'

    trackid = Column(BigInteger, primary_key=True)
    formdata = Column(String(100), nullable=False)

e = create_engine("mysql://scott:tiger@localhost/test", echo=True)
Base.metadata.create_all(e)

s = Session(e)

updateRecord = TrackingTable(formdata='logged in')

s.add(updateRecord)
s.commit()

print updateRecord.trackid

輸出(刪除日志垃圾):

SELECT DATABASE()
SHOW VARIABLES LIKE 'character_set%%'
SHOW VARIABLES LIKE 'sql_mode'
DESCRIBE `tracking_table`
ROLLBACK

CREATE TABLE tracking_table (
trackid BIGINT NOT NULL AUTO_INCREMENT, 
formdata VARCHAR(100) NOT NULL, 
PRIMARY KEY (trackid)
)

COMMIT
BEGIN (implicit)
INSERT INTO tracking_table (formdata) VALUES (%s)
('logged in',)
COMMIT
BEGIN (implicit)
SELECT tracking_table.trackid AS tracking_table_trackid, tracking_table.formdata AS tracking_table_formdata 
FROM tracking_table 
WHERE tracking_table.trackid = %s
(1L,)
1

你需要先刷新你的會話,然后它會知道你的索引位置要增加(我在這里借用@zzzeek的代碼示例):

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
class TrackingTable(Base):
    __tablename__ = 'tracking_table'
    trackid = Column(BigInteger, primary_key=True)
    formdata = Column(String(100), nullable=False)

e = create_engine("mysql://scott:tiger@localhost/test", echo=True)
Base.metadata.create_all(e)
s = Session(e)
# table tracking_table already exists, flush session to get index position
s.flush()
# you can now add new record 
updateRecord = TrackingTable(formdata='logged in') 
s.add(updateRecord)
s.commit()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM