Note: We no longer publish the latest version of our code here. We primarily use a kumc-bmi github organization. The heron ETL repository, in particular, is not public. Peers in the informatics community should see MultiSiteDev for details on requesting access.

source: heron_load/capture_query.py @ 0:42ad7288920a

heron-michigan tip
Last change on this file since 0:42ad7288920a was 0:42ad7288920a, checked in by Matt Hoag <mhoag@…>, 6 years ago

Merge with demo_concepts_3800

File size: 3.7 KB
Line 
1'''capture_query -- capture a query for performance/regression testing
2
3Usage::
4  $ python capture_query.py QUERY_NAME 'query description'
5
6The deid_host, deid_port, deid_sid configuration comes from heron-test.ini.
7
8QUERY_NAME must be a substring of exactly one QT_QUERY_MASTER.NAME.
9
10:copyright: Copyright 2010-2013 University of Kansas Medical Center
11            part of the `HERON open source codebase`__;
12            see NOTICE file for license details.
13
14__ http://informatics.kumc.edu/work/wiki/HERON
15'''
16
17import datetime
18import json
19import logging
20
21from db_util import make_configure_db
22
23
24log = logging.getLogger(__name__)
25TEST_DIR = 'test_queries'
26
27
28def main(argv, auxfile, configure_db,
29        db_section='deid',
30        logger_name='capture_query'):
31    config_fn, qname, description = argv[1:4]
32
33    db, host_port, events, sid = configure_db(config_fn,
34                                              db_section, logger_name)
35
36    capture(db, sid, host_port[0], qname,
37            description, auxfile, ambiguous_error=False)
38
39
40def capture(db, sid, host, qname, description, auxfile, ambiguous_error=True):
41    with db.transaction('$find_query') as q:
42        q.execute('''
43                  select * from BlueHeronData.qt_query_master
44                  where name like ('%' || :name || '%')
45                  ''', dict(name=qname))
46        colnames = [col[0] for col in q.description]
47        log.debug('columns: %s', colnames)
48        ans = q.fetchall()
49        if not ans:
50            raise KeyError(qname)
51        if len(ans) > 1:
52            if ambiguous_error:
53                raise ValueError(ans)  # nicer diagnostic about ambiguous name
54            else:
55                log.warn('ambiguous name; taking 1st one from: %s', ans)
56                del ans[1:]
57        values = [
58            v if type(v) in (type(1), type(''), type(None)) else str(v)
59            for v in ans[0]]
60        log.debug('values: %s', values)
61        record = dict(zip(colnames, values))
62
63        # Go ahead and capture sid, host while we're at it.
64        record['sid'] = sid
65        record['host'] = host
66        record['description'] = description
67
68    when = ans[0][colnames.index('CREATE_DATE')]
69    fn = '%s_%s_%s' % (datetime.datetime.date(when).isoformat(),
70                       record['QUERY_MASTER_ID'],
71                       record['USER_ID'])
72
73    json.dump(record, auxfile(fn, '.json'), indent=2)
74    genSql = record['GENERATED_SQL']
75    if genSql is not None:
76        genSql = genSql.replace('\r\n', '\n')
77        with auxfile(fn, '.sql') as sql:
78            sql.write(record['GENERATED_SQL'].replace('<*>', ';'))
79    else:
80        log.warn('null GENERATED_SQL')
81    with auxfile(fn, '.xml') as xml:
82        xml.write(record['I2B2_REQUEST_XML'])
83
84
85if __name__ == '__main__':
86    logging.basicConfig(level=logging.INFO)
87
88    def _with_caps(main):
89        from getpass import getuser
90        from os import environ
91        from os.path import join
92        from sys import argv
93        import datetime
94        from time import time
95
96        def cx():
97            import cx_Oracle
98            return cx_Oracle
99
100        def open_arg(n):
101            if not n in argv:
102                raise IOError("not an authorized CLI arg: %s" % n)
103            return open(n)
104
105        def auxfile(fn, ext):
106            return open(join(TEST_DIR, fn + ext), 'wb')
107
108        configure_db = make_configure_db(
109            open_arg,
110            fileConfig=lambda *args, **kwargs: None,
111            getLogger=logging.getLogger,
112            getuser=getuser, environ=environ,
113            calendar=datetime.date, timer=time,
114            dbi=cx)
115
116        return main(argv=argv,
117                    auxfile=auxfile,
118                    configure_db=configure_db)
119
120    _with_caps(main)
Note: See TracBrowser for help on using the repository browser.