A little bit of probing shows the difference between the two:
For: db.tbl[0] = dict(name='something')
File "/var/web2py/gluon/globals.py", line 172, in <lambda>
self._caller = lambda f: f()
File "/var/web2py/applications/myapp/controllers/default.py", line 114, in test
db.tbl[0] = dict(name='something')
File "/var/web2py/gluon/dal.py", line 5531, in __setitem__
self.insert(**self._filter_fields(value))
File "/var/web2py/gluon/dal.py", line 5605, in insert
return self._db._adapter.insert(self,self._listify(fields))
For: db.tbl.insert(name='something')
File "/var/web2py/gluon/globals.py", line 172, in <lambda>
self._caller = lambda f: f()
File "/var/web2py/applications/myapp/controllers/default.py", line 115, in test
db.tbl.insert(name='something')
File "/var/web2py/gluon/dal.py", line 5605, in insert
return self._db._adapter.insert(self,self._listify(fields))
Both of them end up calling the same code to do the insert, so you will see that they run the same query:
INSERT INTO tbl(name) VALUES ('something');
Since the former does _filter_fields
as is apparent from the trace, it does not thrown an exception when there are fields that are not present in the table, while the other does.
Obviously, db.tbl[0] = newRow
cannot return a value. You should just consider it a shorthand for insert and its cousin db.tbl[x>0]
is extremely useful for updates and has the exact same notation and this helps simplify the code.