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

时间:2015-06-21 17:11:23

标签: python sqlite web2py

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

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,并期望在这里有类似的行为。

2 个答案:

答案 0 :(得分:1)

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

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

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

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

答案 1 :(得分:1)

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