How to properly specify "query condition" for the genquery.py module

73 views
Skip to first unread message

Tony S

unread,
Jul 31, 2019, 8:53:29 AM7/31/19
to iRODS-Chat
Hello community,

Can someone help me on how to properly specify "query condition" when calling the irods genquery.py function (here: https://irods.org/2018/09/genquery-iterator-for-the-irods-python-rule-engine-plugin/) in python.

I found examples where conditions were specified with specific object-names like alice in "DATA_OWNER_NAME = 'alice'" below:


from genquery import ( row_iterator, paged_iterator, AS_DICT, AS_LIST )
# ...
def findMyObjects(rule_args, callback, rei):
   
My_Results_List = []
    rows
= row_iterator(
           
["COLL_NAME","DATA_NAME"],   # requested columns
           
"DATA_OWNER_NAME = 'alice'", # condition for query
            AS_DICT
,                     # retrieve as key/value structure
            callback
)
   
for row in rows:
       
My_Results_List.append("{COLL_NAME}/{DATA_NAME}".format(**row))

Or file path (/tempZone/home/rods) in COLL_NAME = '/tempZone/home/rods'"

My question is, how can I specify the variable holding the file path as the query condition? I am trying to apply metadata to the siblings of the object in the current session in irods. And I noticed that my code only works when I give specific name like '/tempZone/home/rods' or 'alice'. I don't want to apply the rule to a hardcoded name.

Your help will be highly appreciated!

Thanks
Tony

dmoore.renci

unread,
Jul 31, 2019, 1:07:13 PM7/31/19
to iRODS-Chat
hi Tony,

  Because the genquery.py module is just a thin wrapper over the genquery microservices, the query condition argument (a string variable) will be much the same as if you were sending your arguments straight to the microservices themselves. Note therefore, the word "WHERE" should _not_ be included the condition string; otherwise though , the condition is formatted exactly as in the WHERE clauses of the Language Integrated General Query.


  Things to remember: the COLL_NAME that matches in the query will be the parent collection in which the data object resides, and the DATA_NAME that matches will be the base-name part only (the data object's name without the parent collection).

  So, to target (for example) data objects with extension ".txt" in eg.  your home Collection or a sub-collection thereof
(assuming that in your use case a "sibling" is any other data object found inhabiting the same parent collection as the data object matched):


import session_vars
from genquery import AS_DICT, row_iterator
# ...
def find_siblings(rule_args, callback, rei):

    user_dict = dict(session_vars.get_map(rei)["client_user"])
    home_collection = "/" + user_dict [ "irods_zone" ] + "/home/" +  user_dict [ "user_name" ]
    # callback.writeLine('stdout','{0}'.format(home_collection))
    dataName = ""
    for obj in row_iterator ( [ "COLL_NAME", "DATA_NAME", ],
                              "COLL_NAME = '{0}' || like '{0}/%' and DATA_NAME like '%.txt'".format(home_collection), AS_DICT, callback ):
      dataName = obj["DATA_NAME"]
      collName = obj["COLL_NAME"]

    if dataName:

      for obj in row_iterator ( [ "COLL_NAME", "DATA_NAME", ],
                                "COLL_NAME = '{0}' and DATA_NAME != '{1}'".format( collName, dataName ), AS_DICT, callback):

        # note the AND part of the clause          ^^^^
        #    which excludes the data object with the name that matched in the last query
        #    omit that 'and' part if you want an inclusive "sibling" match

        d_obj = obj["DATA_NAME"]  # < -- gets iterated for all siblings

        callback.writeLine("stdout", "sibling at : {0}/{1}".format ( obj["COLL_NAME"] , obj["DATA_NAME"] ))

#       # the above formatting call could be abbreviated as {COLL_NAME}/{DATA_NAME}".format(**obj)
#       #       ( -- do your metadata magic here with the sibling data object-- )


Hope the above helps!

-Daniel Moore
Applications Engineer
iRODS Consortium

Tony S

unread,
Aug 14, 2019, 8:45:21 AM8/14/19
to iRODS-Chat
Hi Daniel,

Sorry for my late reply.
Thank you for your response and providing the code. It indeed worked and helped me realized where my mistake was!

Best,
Tony
Reply all
Reply to author
Forward
0 new messages