在sqlite3中没有Integer主键的自动增量

时间:2012-07-15 07:00:01

标签: python sqlite

在sqlite3 faq中,提到了一个为空值提供的整数主键会自动增加。但这不会发生在我身上。

复制,sqlite3中的表,CREATE TABLE dummy( serial_num INTEGER PRIMARY KEY, name TEXT);并使用python填充它,

import sqlite3 as lite
con = lite.connect('some.db')
cur=con.cursor()
data = "someone's name"
cur.execute("INSERT INTO dummy VALUES(NULL, ?)", data)
con.commit()

第一个属性serial_num显示为空白,而name属性正常。当我做SELECT serial_num FROM dummy时,我只是得到了一堆空格。我做错了什么?

2 个答案:

答案 0 :(得分:26)

这是SQLite的一个怪癖。来自fine manual

  

根据SQL标准,PRIMARY KEY应始终表示NOT NULL。不幸的是,由于长期的编码监督,在SQLite中并非如此。除非列是INTEGER PRIMARY KEY,否则SQLite允许在PRIMARY KEY列中使用NULL值。我们可以改变SQLite以符合标准(我们将来也可以这样做),但是当发现疏忽时,SQLite的使用范围很广,如果我们解决问题,我们担心会破坏遗留代码。

INTEGER PRIMARY KEY上的文档有点不清楚列是什么精确需要这个特殊的INTEGER PRIMARY KEY自动递增,但实际情况是如果你想要列,则列需要为NOT NULL插入时使用NULL值表示“给我下一个自动递增值”:

create table dummy (
    serial_num integer primary key not null,
    name text
);

如果遗漏not null,则需要按照以下方式进行插入:

insert into dummy (name) values (?)

获取serial_num的自动增量值。否则,SQLite无法区分NULL意味着“给我下一个自动增量值”和NULL意味着“将NULL值放在serial_num中,因为该列允许NULL”。

答案 1 :(得分:2)

在没有not null的情况下,上面提供的插入语法似乎不起作用。

以下是一个示例 - 请注意,即使我使用您在上面指定的插入格式,ID字段也不会自动增加。

sqlite> .schema logTable
CREATE TABLE logTable (ID INTEGER PRIMARY_KEY, ts REAL, level TEXT, message TEXT);
sqlite> INSERT into LOGTABLE (ts, level, message) VALUES (111, "autoinc test", "autoinc test");
sqlite> select * from logtable where ts = 111;
|111.0|autoinc test|autoinc test
sqlite> 

它适用于NOT NULL解决方法。

sqlite> create TABLE logTable (ID INTEGER PRIMARY KEY NOT NULL, ts REAL, level TEXT, message TEXT);
sqlite> INSERT into LOGTABLE (ts, level, message) VALUES (222, "autoinc test", "autoinc test"); 
sqlite> select * from logtable where ts = 222;
1|222.0|autoinc test|autoinc test

我很抱歉将此作为新答案发布而不是评论之前的答案,但我的声誉评分太低而无法添加评论,我认为重要的是要注意备用插入语句不是一个适当的解决方法