This may be something that is known by people with more experience than me, but it took me a lot of experimenting to figure it out, so I thought I would post it here so others will find it.
I have legacy sqlite tables that do not have an id field. This makes it difficult to update them using SQLFORM.
ROWID is a hidden auto-increment integer field that's included in all sqlite tables. You can make ROWID explicit by declaring it as the first field in a table definition, then you can assign it the 'id' alias.
Here's an example:
db.define_table('my_sqlite_table',
Field('ROWID', 'id'),
Field('some_field', 'string'),
Field('some_other_field', 'integer'),
........
migrate=False)
You can then use 'id' as a field name just as if your table had an actual id field defined in the underlying table. As far as I can tell, this hack works without any problems. The use of the 'id' alias is documented, but I haven't seen the use of 'ROWID' with the alias discussed. This might be something that could be tested and added to the documentation.