I tried another field name, but result the same. I think dal has incomplete handling of custom types. I analyzed dal code and found that constructed query for my example was:
INSERT INTO posts(content,html,title) VALUES (\xd0\x94\xd0\xb2\xd0\xb0,\xd0\xa2\xd1\x80\xd0\xb8,\xd0\x9e\xd0\xb4\xd0\xb8\xd0\xbd); As you can see values are not enclosed by quotes. This is incorrect as for me. I rewrote my custom type: utext = SQLCustomType( type="text", native="text", encoder = lambda x: "'%s'" % x.replace("'", "''").encode("utf-8"), decoder = lambda x: x.decode("utf-8") ) And it works after such update, but example from the web2py book wouldn't work also: compressed = SQLCustomType( type ='text', native='text', encoder =(lambda x: zlib.compress(x or '')), decoder = (lambda x: zlib.decompress(x)) ) Further analysis shown that DAL doesn't check SQLCustomType.type while constructing query and simply calls SQLCustomType.encoder(). But it should check the type of SQLCustomType and enclose it with quotes in case of string/text type. I updated BaseAdapter.represent() with following code: ... if isinstance(fieldtype, SQLCustomType): if fieldtype.type == "string" or fieldtype.type == "text": # added return self.adapt(fieldtype.encoder(obj)) # added return fieldtype.encoder(obj) ... Now my custom type doesn't require code that adds quotes - now this does DAL. =) Could you comment how my fix fits DAL design?