At CHUM we are implementing some tests that will import data from DQA3 automatically to avoid having to transfer the data manually.
We are currently using version 0.27 of QATrack+.
We added a composite string test called importdqa with the code found bellow. The code outputs the data in a dictionary that is converted to json format so it fits into the string. This json data is then loaded by the other composite tests that will hold the individual values for the measures with code that looks like this:
import json
dqa = json.loads(importdqa)
if ('output_6mv' in dqa):
spro_output_6mv = dqa['output_6mv']
Here we have a composite test named spro_output_6mv that loads the output of the dqa3 query string composite. There are additional composite tests that calculate symetry and other tests.
Any comments or questions are welcome.
<CODE>
importdqa='ok' # if we get an error, this test will contain an error message
# vim: set sw=4 ts=8 sts=4 et foldmethod=indent fileencoding=utf-8 :
#===============================================================================
#
# FILE: importdqa.py
#
# DESCRIPTION: Read DQA3 data to populate QATrack database
# DQA3 uses a Firebird 1.5 database to store it's data
#
# AUTHOR: Stefan Michalowski
# Ellis Mitrou
# COMPANY: CHUM
# VERSION: 1.0
# CREATED: 2018-07-25
# REVISION: ---
#===============================================================================
import MySQLdb # needed to get room serial number
import fdb # needed to talk with firebird database
import json # needed to send data out to other tests
exportdata=dict() # data that will be exported will be in a dictionary that will be jsoned into string
try: # catching errors with fdb
unit_number = META['unit_number'] # retrieve unit number but we need serial number
# we connect to the qatrack database to get the unit serial number (that is defined in the DQA3 database)
qatrack_db = MySQLdb.connect(host="localhost", user="qatrack_user", passwd="qatrack_password", db="qatrack_db")
qatrack_cursor = qatrack_db.cursor()
qatrack_cursor.execute("SELECT serial_number FROM units_unit WHERE number = %s",(unit_number,))
if qatrack_cursor.rowcount > 0:
row = qatrack_cursor.fetchone() # serial number is in row[0]
# now we connect to the DQA3 database, we had to create a special readdata user in the database
dqa3_conn = fdb.connect( host='dqa3_hostname', database='dqa3_database', port=3050, user='dqa_read_user', password='dqa_read_password')
dqa3_cursor = dqa3_conn.cursor()
# this is the query in the DQA3 database that retrieves today's latest measurements per room/energy
sql_query = """
SELECT
r.tree_name AS Room
,e.tree_name AS Energy
,SUBSTRING(CAST (a.measured_datetime AS VARCHAR(24)) FROM 1 FOR 16) AS measured_datetime
,((a.t_counts-a.t_offset)-a.t_bkg*(a.session_time-a.offset_time))*k.t_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS T_dose
,((a.r_counts-a.r_offset)-a.r_bkg*(a.session_time-a.offset_time))*k.r_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS R_dose
,((a.b_counts-a.b_offset)-a.b_bkg*(a.session_time-a.offset_time))*k.b_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS B_dose
,((a.l_counts-a.l_offset)-a.l_bkg*(a.session_time-a.offset_time))*k.l_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS L_dose
,((a.c_counts-a.c_offset)-a.c_bkg*(a.session_time-a.offset_time))*k.c_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS C_dose
FROM
dqa3_data a
INNER JOIN dqa3_template e ON a.set_key = e.set_key
INNER JOIN dqa3_machine m ON e.mach_key = m.mach_key
AND m.MACHSERIAL = ?
INNER JOIN room r ON m.room_key = r.room_key
INNER JOIN device v ON a.device_key = v.device_key
INNER JOIN dqa3_calibration k ON v.device_key = k.device_key
AND a.cal_key = k.cal_key
WHERE
a.flags != 5
AND CAST (a.measured_datetime AS DATE) = CAST ('Now' AS DATE)
AND a.measured_datetime = (
SELECT
MAX(data.measured_datetime)
FROM
dqa3_data data
INNER JOIN dqa3_template template ON data.set_key = template.set_key
AND template.tree_name = e.tree_name
INNER JOIN dqa3_machine machine ON template.mach_key = machine.mach_key
AND machine.MACHSERIAL = m.MACHSERIAL
WHERE
a.flags != 5
AND CAST (data.measured_datetime AS DATE) = CAST ('Now' AS DATE)
GROUP BY
machine.MACHSERIAL
,template.tree_name
)
"""
dqa3_cursor.execute(sql_query,(str(row[0]),)) # row[0] has the unit serial number
#loop over results, we output in a dictionary with the keys being of measure_energy format (ex.: bottom_6mv, left_10fff)
for (room,energy,measured_datetime,top,right,bottom,left,output) in dqa3_cursor:
exportdata['bottom_' + str(energy).replace(' ','').lower()] = bottom
exportdata['top_' + str(energy).replace(' ','').lower()] = top
exportdata['left_' + str(energy).replace(' ','').lower()] = left
exportdata['right_' + str(energy).replace(' ','').lower()] = right
exportdata['output_' + str(energy).replace(' ','').lower()] = output
if len(exportdata) > 0:
importdqa = json.dumps(exportdata) # convert output to json so it can be read by the other tests
else:
importdqa = 'No DQA3 data found'
else:
importdqa = "Unit not found"
except fdb.fbcore.ProgrammingError as e:
importdqa = "ProgrammingError: " + str(e)
except fdb.fbcore.DatabaseError as e:
importdqa = "DatabaseError: " + str(e)
except ValueError as e:
importdqa = "ValueError: " + str(e)
except TypeError as e:
importdqa = "TypeError: " + str(e)
except Exception as e:
importdqa = "Exception: " + str(e)
except:
importdqa = "Unknown Error"
</CODE>
Regards,
--
Stefan Michalowski (g_m...@ptaff.ca)
from qatrack.units.models import Unit
serial_num = Unit.objects.get(number=META['unit_number']).serial_number
--
You received this message because you are subscribed to the Google Groups "QATrack+" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qatrack+u...@googlegroups.com.
To post to this group, send email to qat...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to qatrack+unsubscribe@googlegroups.com.
To post to this group, send email to qat...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
To unsubscribe from this group and stop receiving emails from it, send an email to qatrack+u...@googlegroups.com.
To post to this group, send email to qat...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
New version of the code, with some improvements: user can get data from a previous date by entering it in the work_started, uses Django ORM instead of MySQL to get unit serial number, checks if work_completed is set or not to avoid reloading the data if this is a review.
<CODE>
importdqa='ok' # if we get an error, this test will contain an error message
# vim: set sw=4 ts=8 sts=4 et foldmethod=indent fileencoding=utf-8 :
#===============================================================================
#
# FILE: importdqa.py
#
# DESCRIPTION: Read DQA3 data to populate QATrack database
# DQA3 uses a Firebird 1.5 database to store it's data
#
# AUTHOR: Stefan Michalowski (stefan.mich...@ssss.gouv.qc.ca)
# Ellis Mitrou (ellis.mi...@ssss.gouv.qc.ca)
# COMPANY: CHUM
# VERSION: 1.2
# CREATED: 2018-07-25
# REVISION: 1.0 -- 2018-07-25 Initial version
# 1.1 -- 2018-07-26 Do not load if work_completed is filled
# Use work_started to filter DQA3 data
# 1.2 -- 2018-07-30 Replace MySQL query for Unit serial number by Django ORM code
# as suggested by Randle Taylor
#===============================================================================
import fdb # needed to talk with firebird database
import json # needed to send data out to other tests
from qatrack.units.models import Unit # needed to get Unit serial number
exportdata=dict() # data that will be exported will be in a dictionary that will be jsoned into string
work_completed = META['work_completed']
try: # catching errors with fdb
if ((work_completed is None) or (work_completed == '')): # DO not load data if work_completed is entered
serial_num = Unit.objects.get(number=META['unit_number']).serial_number
work_started = META['work_started'] # we will use work_started to filter DQA3 data so user can specify data from a specific date
if not ( (serial_num is None) or (serial_num == '') ):
# now we connect to the DQA3 database, we had to create a special readdata user in the database
dqa3_conn = fdb.connect( host='dqa_hostname', database='dqa3_database', port=3050, user='dqa_read_user', password='dqa_read_password')
dqa3_cursor = dqa3_conn.cursor()
# this is the query in the DQA3 database that retrieves today's latest measurements per room/energy
sql_query = """
SELECT
r.tree_name AS Room
,e.tree_name AS Energy
,SUBSTRING(CAST (a.measured_datetime AS VARCHAR(24)) FROM 1 FOR 16) AS measured_datetime
,((a.t_counts-a.t_offset)-a.t_bkg*(a.session_time-a.offset_time))*k.t_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS T_dose
,((a.r_counts-a.r_offset)-a.r_bkg*(a.session_time-a.offset_time))*k.r_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS R_dose
,((a.b_counts-a.b_offset)-a.b_bkg*(a.session_time-a.offset_time))*k.b_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS B_dose
,((a.l_counts-a.l_offset)-a.l_bkg*(a.session_time-a.offset_time))*k.l_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS L_dose
,((a.c_counts-a.c_offset)-a.c_bkg*(a.session_time-a.offset_time))*k.c_factor*v.ab_dose_cf*e.template_dose_cf*((a.temperature+273.2)/295.2*(101.33/a.pressure)) AS C_dose
FROM
dqa3_data a
INNER JOIN dqa3_template e ON a.set_key = e.set_key
INNER JOIN dqa3_machine m ON e.mach_key = m.mach_key
AND m.MACHSERIAL = '%s'
INNER JOIN room r ON m.room_key = r.room_key
INNER JOIN device v ON a.device_key = v.device_key
INNER JOIN dqa3_calibration k ON v.device_key = k.device_key
AND a.cal_key = k.cal_key
WHERE
a.flags != 5
AND CAST (a.measured_datetime AS DATE) = CAST ('%s' AS DATE)
AND a.measured_datetime = (
SELECT
MAX(data.measured_datetime)
FROM
dqa3_data data
INNER JOIN dqa3_template template ON data.set_key = template.set_key
AND template.tree_name = e.tree_name
INNER JOIN dqa3_machine machine ON template.mach_key = machine.mach_key
AND machine.MACHSERIAL = m.MACHSERIAL
WHERE
a.flags != 5
AND CAST (data.measured_datetime AS DATE) = CAST (a.measured_datetime AS DATE)
GROUP BY
machine.MACHSERIAL
,template.tree_name
)
"""
dqa3_cursor.execute(sql_query % (serial_num,work_started.strftime("%Y-%m-%d")))
I remember you mentioned potentially creating a site where tests can be shared. This would be a nice addition to that I think.
Cheers,
Simon
Dne torek, 31. julij 2018 00.51.36 UTC+2 je oseba Simon Biggs napisala:
--
You received this message because you are subscribed to a topic in the Google Groups "QATrack+" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/qatrack/YvS4PcfQRNg/unsubscribe.
To unsubscribe from this group and all its topics, send an email to qatrack+unsubscribe@googlegroups.com.
To post to this group, send email to qat...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
Dear Stefan, thank you for the SQL code about daily QA3 data import.
I have a question about DailyQA3....is not really linked to QATrack + until now. But I need first to merge 2 firebird database from DailyQA3 could you help me for that ? Thank you
--
You received this message because you are subscribed to the Google Groups "QATrack+" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qatrack+u...@googlegroups.com.
To post to this group, send email to qat...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qatrack/4030b50f-3afa-48ae-9551-51df5f834799%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.
--
You received this message because you are subscribed to the Google Groups "QATrack+" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qatrack+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qatrack/cf0e212b-e6a7-4f15-a7d6-f5cdef694c6a%40googlegroups.com.
--
You received this message because you are subscribed to the Google Groups "QATrack+" group.
To unsubscribe from this group and stop receiving emails from it, send an email to qatrack+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qatrack/905891e4-4a70-4e49-86c9-efa530ad656b%40googlegroups.com.
import fdb
dqa3_conn = fdb.connect( host='OXNETWIKI01', database='SNCData', port=3050, user='QATUSER', password='qatpass')(qatrack3) C:\deploy\venvs\qatrack3\Scripts>python C:\Usersop\QATracFDB.pyTraceback (most recent call last): File "C:\Users\Harkirat.Singh\Desktop\QATracFDB.py", line dqa3_conn = fdb.connect( host='OXNETWIKI01', database='user='QATUSER', password='qatpass') File "C:\deploy\venvs\qatrack3\lib\site-packages\fdb\fbcoconnect load_api(fb_library_name) File "C:\deploy\venvs\qatrack3\lib\site-packages\fdb\fbcoload_api setattr(sys.modules[__name__], 'api', ibase.fbclient_AP File "C:\deploy\venvs\qatrack3\lib\site-packages\fdb\ibas__init__ fb_library = WinDLL(fb_library_name) File "C:\Program Files\Python36\lib\ctypes\__init__.py",
self._handle = _dlopen(self._name, mode)OSError: [WinError 193] %1 is not a valid Win32 applicationTo unsubscribe from this group and stop receiving emails from it, send an email to qat...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qatrack/905891e4-4a70-4e49-86c9-efa530ad656b%40googlegroups.com.
To unsubscribe from this group and stop receiving emails from it, send an email to qatrack+u...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qatrack/94cd2837-ecc4-4758-984a-57fa29d41e8e%40googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/qatrack/f0df278a-feac-48f7-86b1-10c26335095an%40googlegroups.com.