不强制执行数据库字段长度

Database field length is not enforced

我正在使用 web2py (python) 和 sqlite3 数据库(测试花数据库 :))。这是 table:

的声明
db.define_table('flower',
        Field('code', type='string', length=4, required=True, unique=True),
        Field('name', type='string', length=100, required=True),
        Field('description', type='string', length=250, required=False),
        Field('price',  type='float', required=True),
        Field('photo', 'upload'));

在sql.log中翻译成正确的SQL:

CREATE TABLE flower(
    id INTEGER PRIMARY KEY AUTOINCREMENT,
    code CHAR(4),
    name CHAR(200),
    description CHAR(250),
    price CHAR(5),
    photo CHAR(512)
);

但是当我插入一个大于 4 个字符的 "code" 字段的值时,它仍然会插入。我尝试设置为 CHAR(10)(我想是简单测试),结果相同。

>>>db.flower.insert(code="123456789999", name="flower2", description="test flower 2", price="5.00");
>>>1L;

同样的问题适用于我设置长度的所有字段。我也尝试过验证(尽管我不是 100% 正确使用它)。这也在花模型 flowers.py 中,其中定义了 table 并遵循 table 声明:

db.flower.code.requires = [ IS_NOT_EMPTY(), IS_LENGTH(4), IS_NOT_IN_DB(db, 'flower.code')]

关于此的文档是 here,但我找不到任何限制字符串的 SQLite3 或 web2py 长度检查的内容。我希望在插入时看到错误。

需要一些帮助吗?我在文档中遗漏了什么?我之前将 symphony2 与 PHP 和 MySQL 一起使用,并期望这里有类似的行为。

SQLite 与其他数据库不同。对于所有(大多数)实际用途,列都是无类型的,INSERT 将始终成功并且不会丢失数据或精度(这意味着,如果需要,您可以将文本值插入到 REAL 字段中)。

列的声明类型用于名为 "type affinity" 的系统,此处对其进行了描述:https://www.sqlite.org/datatype3.html

一旦你习惯了,它会很有趣——但绝对不是你所期望的!

您必须在发出 INSERT 之前在代码中执行长度检查。

如前所述,SQLite 不强制执行字符字段长度声明(请参阅 https://www.sqlite.org/faq.html#q9)。此外,仅当您通过 SQLFORM 提交或通过 .validate_and_insert 方法进行插入时才应用 IS_LENGTH 验证器——如果您仅使用 .insert 方法,验证器存储在 requires 属性中的未应用,因此您不会收到任何错误。