【问题标题】:Database field length is not enforced未强制执行数据库字段长度
【发布时间】:2015-06-21 17:11:22
【问题描述】:

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

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 个字符的“代码”字段值时,它仍然会插入。我尝试设置为 CHAR(10)(我猜是简单测试),结果相同。

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

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

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

这方面的文档是 here,但我找不到任何限制 SQLite3 或 web2py 字符串长度检查的东西。我希望在插入时看到错误。

在这方面需要一些帮助吗?我在文档中遗漏了什么?我之前在 PHP 和 MySQL 中使用过 symphony2,并且预计会出现类似的行为。

【问题讨论】:

    标签: python sqlite web2py


    【解决方案1】:

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

    列的声明类型用于称为“类型关联”的系统,此处描述为:https://www.sqlite.org/datatype3.html

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

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

    【讨论】:

    • 谢谢拉里。就像我在安东尼的回答下所说的那样:太糟糕了,我不能“接受”两者。我将编写一些插入前检查来强制执行长度。不错!
    【解决方案2】:

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

    【讨论】:

    • 谢谢安东尼。太糟糕了,我不能让两个答案都“被接受”,因为它们很好地互补。这是有道理的,感谢您提供 sqlite 常见问题解答参考。
    猜你喜欢
    • 2015-10-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-18
    • 2011-05-29
    • 2016-08-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多