2012-07-15 20 views
20

En sqlite3 faq, se menciona que una clave primaria entera que se alimenta con un valor nulo se autoincrementaría. Pero esto no está sucediendo para mí.Sin autoincrement para la clave principal Integer en sqlite3

para replicarse, una mesa en sqlite3, CREATE TABLE dummy(serial_num INTEGER PRIMARY KEY, name TEXT); y llenarlo usando pitón,

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() 

La primera SERIAL_NUM atributo se está mostrando en blanco mientras el atributo de nombre es bien. Cuando hago SELECT serial_num FROM dummy acabo de obtener un montón de espacios en blanco. ¿Qué estoy haciendo mal?

+0

Debo agregar, que intenté definir el esquema como '... serial_num INTEGER PRIMARY KEY NOT NULL ...' y obtener el error 'sqlite3.IntegrityError: dummy.serial_no may not null' – yayu

Respuesta

25

Esta es una de las peculiaridades de SQLite. Desde el fine manual:

According to the SQL standard, PRIMARY KEY should always imply NOT NULL. Unfortunately, due to a long-standing coding oversight, this is not the case in SQLite. Unless the column is an INTEGER PRIMARY KEY SQLite allows NULL values in a PRIMARY KEY column. We could change SQLite to conform to the standard (and we might do so in the future), but by the time the oversight was discovered, SQLite was in such wide use that we feared breaking legacy code if we fixed the problem.

La documentación sobre INTEGER PRIMARY KEY es un poco confuso sobre lo que precisamente se requiere para una columna que ser especial PRIMARY KEY INTEGER que auto-incrementos pero la realidad es que la columna debe ser NOT NULL Si desea utilizar el valor NULL en el sentido de "dame el siguiente valor de incremento automático" cuando se inserta:

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

Si se omite la not null, que tiene que hacer su inserta la siguiente manera:

insert into dummy (name) values (?) 

para obtener el valor de incremento automático para serial_num. De lo contrario, SQLite no tiene forma de decir la diferencia entre un valor NULL que significa "darme el siguiente valor de autoincremento" y un valor NULL que significa "poner un valor NULL en serial_num porque la columna permite NULLs".

+1

Muchas gracias. Al experimentar, también aprendí que la autoincrementación funciona solo con una columna como clave principal. – yayu

+0

@yayu: Esa parte de la [documentación] (http://www.sqlite.org/lang_createtable.html#primkeyconst) es bastante clara al menos: "Si una tabla tiene una clave primaria de columna única, y el tipo declarado de esa columna es 'INTEGER' ..." –

2

La sintaxis de inserción proporcionada anteriormente no parece funcionar en ausencia de not null.

Aquí hay un ejemplo: tenga en cuenta que el campo ID no se ha autoincrementado aunque use el formato de inserción que especificó anteriormente.

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> 

Funciona con la solución 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 

me disculpo por publicar esto como una nueva respuesta en vez de comentar la respuesta anterior, pero mi puntuación de reputación es demasiado baja para añadir comentarios, y pensé que era importante tener en cuenta que la instrucción de inserción alternativa es no es una solución adecuada.

Cuestiones relacionadas