Meh*_*dad 3 python sqlite primary-key composite-primary-key
代码:
import sqlite3
c = sqlite3.Connection(':memory:')
c.execute('CREATE TABLE foo(a INTEGER, b VARCHAR(8), PRIMARY KEY(a, b))')
c.execute('INSERT INTO foo(a) VALUES (1)')
c.execute('INSERT INTO foo(a) VALUES (1)')
print(c.execute('SELECT * FROM foo').fetchall())
Run Code Online (Sandbox Code Playgroud)
输出:
[(1, None), (1, None)]
Run Code Online (Sandbox Code Playgroud)
为什么 SQLite 插入具有重复主键的行?我该如何解决?
SQL PK (PRIMARY KEY) 表示 UNIQUE NOT NULL。您不应该期望 PK 的值中有一个 NULL,更不用说只有一个了。您应该声明 PK 列 NOT NULL 并且不要将 NULL 放入其中。
具有主键的表中的每一行都必须在其主键列中具有唯一的值组合。为了确定主键值的唯一性,NULL 值被视为与所有其他值(包括其他 NULL)不同。如果 INSERT 或 UPDATE 语句尝试修改表内容以使两行或更多行具有相同的主键值,则违反约束。
根据 SQL 标准,PRIMARY KEY 应该总是暗示 NOT NULL。不幸的是,由于某些早期版本中的错误,SQLite 中并非如此。除非该列是一个 INTEGER PRIMARY KEY 或者该表是一个 WITHOUT ROWID 表或者该列被声明为 NOT NULL,否则 SQLite 允许在 PRIMARY KEY 列中使用 NULL 值。可以修复 SQLite 以符合标准,但这样做可能会破坏遗留应用程序。因此,决定仅记录 SQLite 在大多数 PRIMARY KEY 列中允许 NULL 的事实。
由于 PK 中的 NULL 是针对 SQL 的,因此在 PK 中使用 NULL 约束和操作表时,SQLite 选择做什么似乎没有实际意义。但它使用通常的 SQL 解释,即出于 UNIQUE 的目的,NULL 不等于 NULL。这就像当您声明一个列集 UNIQUE NULL 时。所以作为一个约束,SQLite PK 是 UNIQUE 而不是 UNIQUE NOT NULL 的同义词。
UNIQUE 约束类似于 PRIMARY KEY 约束,不同之处在于单个表可以具有任意数量的 UNIQUE 约束。对于表上的每个 UNIQUE 约束,每一行都必须包含 UNIQUE 约束标识的列中的唯一值组合。出于 UNIQUE 约束的目的,NULL 值被视为与所有其他值(包括其他 NULL)不同。