Bug 1388921

Summary: Python API ovs.db.idl.Row.setkey does not work on new Rows
Product: Red Hat Enterprise Linux 7 Reporter: Marcin Mirecki <mmirecki>
Component: openvswitchAssignee: Open vSwitch development team <ovs-team>
Status: CLOSED NOTABUG QA Contact: Network QE <network-qe>
Severity: medium Docs Contact:
Priority: medium    
Version: 7.1CC: aconole, aloughla, atragler, mmirecki
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: If docs needed, set a value
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2016-11-08 17:06:27 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Marcin Mirecki 2016-10-26 13:09:45 UTC
ovs.db.idl.Row.setkey does not work on newly created row.

Trying to execute code:

  transaction = ovs.db.idl.Transaction(self._ovsdb_connection)
  row = transaction.insert(self._ovsdb_connection.tables['<table name>'])
  row.setkey('<column>', '<key>', '<value>')

Will result in:

File "/usr/lib/python2.7/site-packages/ovs/db/idl.py", line 873, in setkey
    if column_name in self._data:
TypeError: argument of type 'NoneType' is not iterable

Comment 2 Aaron Conole 2016-10-26 18:43:43 UTC
Please write a more detailed issue.  The row in your code block doesn't exist yet (because the transaction wasn't committed), and I'm not sure if there exists a column with the name you've asked (because of the values in your example code).

Please post the minimum runnable version of code that fails.

Comment 3 Marcin Mirecki 2016-11-07 08:47:47 UTC
Does this not create a row:
row = transaction.insert(self._ovsdb_connection.tables['<table name>'])

If we have to commit the transaction before we add further fields, we end up with a partial transaction which is somewhat useless.


IMO it would not take much to extend the "setkey" method to cover this scenario as well. 
Currently you have to do this manually:

row = transaction.insert(self._ovsdb_connection.tables['<table name>'])
options = getattr(row, 'options', {})
options['key'] = 'value'

Not a lot of work, but since we have "setkey" I would expect to be able to use it here too.

Comment 4 Aaron Conole 2016-11-08 17:06:27 UTC
You don't have to commit the transaction before adding fields - but you do have to setup the keys before committing.  If you commit otherwise, it likely won't even be added to the database, because the schema validation would fail.

The architecture for this is quite complicated for very good reasons.  Please see the documentation in the IDL.py for some explanations on why we must set rows the way we do.

In the meantime, I'm closing this - it isn't a bug.