[英]How to copy a row and insert in same table with a autoincrement field in 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.