2

在编写以下内容时,我不小心在 sqlite3 的数据类型中输入了错字schema.sql


create table xxx(
    id integer primary key autoincrement not null,
    num integet
)

如您所见,integet应该是integer,但它仍然有效,这意味着我可以将数据插入其中。为什么?我怎样才能在integer不破坏数据库的情况下纠正它?

4

2 回答 2

2

正如Pythonsqlite3模块数据库本身的文档所解释的那样,sqlite3 是无类型的。您可以将字符串值插入一INTEGER列,或将整数值插入一VARCHAR列。

但是,sqlite 有一个称为“列关联”的功能,如果列类型是 INTEGER 等,它将尝试以数字方式处理参数。Python 模块尝试将每个 sqlite 类型映射到 Python 类型,所以如果 sqlite 给它INTEGER 列,Python 会将其映射到整数类型。

正如相应的文档所解释的:

如果声明的类型包含字符串“INT”,则为其分配 INTEGER 亲和性。

INTEGER int 或 long,取决于大小

比较不区分大小写。任何不符合任何规则的内容都将被视为NUMERIC,Python 将其视为str/ bytes/ buffer(取决于您的版本)。

因此,对于 sqlite 本身,integet匹配规则INTEGER,因此,您可以存储整数值并将它们作为整数检索。(当然,您仍然可以存储'abc',并将其作为字符串取回。)Python 会将其视为一INTEGER列,因此int尽可能读取值。


至于你问题的最后一部分,sqlite3 没有提供任何方法在创建列后更改它的类型。事实上,该ALTER TABLE命令只允许添加新列或约束,或重命名表。

如果您需要修改实时数据库,您需要做的是创建一个包含正确列的新表,复制所有内容,删除旧表并重命名新表,如下所示:

CREATE TABLE yyy(id INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, num INTEGER)
INSERT INTO yyy SELECT * FROM xxx
DROP TABLE xxx
ALTER TABLE yyy RENAME TO xxx

您插入到旧表中的任何字符串值都将被复制 - 并且每次您获取它们时,因为列类型是INTEGER,Python 将尝试转换为(int如果可能),而不是将它们保留为bytesor str

于 2013-05-28T09:55:17.877 回答
-1

SQLite 宽容到了愚蠢的地步。您可以创建“wibble”类型的列。这个 CREATE TABLE 语句在 SQLite 中工作。

create table wibble (wibble wibble);

您也可以插入其中。

insert into wibble values ('wibble');
于 2013-05-28T12:09:35.500 回答