Used for comparing the results of a Query across two databases
| 62 | |
| 63 | |
| 64 | class QueryResultComparator(object): |
| 65 | '''Used for comparing the results of a Query across two databases''' |
| 66 | |
| 67 | # Used when comparing FLOAT values |
| 68 | EPSILON = 0.1 |
| 69 | |
| 70 | # The DECIMAL values will be rounded before comparison |
| 71 | DECIMAL_PLACES = 2 |
| 72 | |
| 73 | def __init__(self, query_profile, ref_conn, |
| 74 | test_conn, query_timeout_seconds, flatten_dialect=None): |
| 75 | '''test/ref_conn arguments should be an instance of DbConnection''' |
| 76 | self.ref_conn = ref_conn |
| 77 | self.ref_sql_writer = SqlWriter.create( |
| 78 | dialect=ref_conn.db_type, nulls_order_asc=query_profile.nulls_order_asc()) |
| 79 | self.test_conn = test_conn |
| 80 | self.test_sql_writer = SqlWriter.create(dialect=test_conn.db_type) |
| 81 | |
| 82 | compat.setup_ref_database(self.ref_conn) |
| 83 | |
| 84 | ref_cursor = ref_conn.cursor() |
| 85 | test_cursor = test_conn.cursor() |
| 86 | |
| 87 | self.query_executor = QueryExecutor( |
| 88 | [ref_cursor, test_cursor], |
| 89 | [self.ref_sql_writer, self.test_sql_writer], |
| 90 | query_timeout_seconds=query_timeout_seconds, |
| 91 | flatten_dialect=flatten_dialect) |
| 92 | |
| 93 | @property |
| 94 | def test_db_type(self): |
| 95 | return self.test_conn.db_type |
| 96 | |
| 97 | @property |
| 98 | def ref_db_type(self): |
| 99 | return self.ref_conn.db_type |
| 100 | |
| 101 | def compare_query_results(self, query): |
| 102 | '''Execute the query, compare the data, and return a ComparisonResult, which |
| 103 | summarizes the outcome. |
| 104 | ''' |
| 105 | comparison_result = ComparisonResult(query, self.test_db_type, self.ref_db_type) |
| 106 | (ref_sql, ref_exception, ref_data_set, ref_cursor_description), (test_sql, |
| 107 | test_exception, test_data_set, test_cursor_description) = \ |
| 108 | self.query_executor.fetch_query_results(query) |
| 109 | |
| 110 | comparison_result.ref_sql = ref_sql |
| 111 | comparison_result.test_sql = test_sql |
| 112 | |
| 113 | if ref_exception: |
| 114 | comparison_result.exception = ref_exception |
| 115 | error_message = str(ref_exception) |
| 116 | if 'Year is out of valid range: 1400..9999' in error_message: |
| 117 | # This comes from Postgresql. Overflow errors will be ignored. |
| 118 | comparison_result.exception = TypeOverflow(error_message) |
| 119 | LOG.debug('%s encountered an error running query: %s', |
| 120 | self.ref_conn.db_type, ref_exception, exc_info=True) |
| 121 | return comparison_result |
no outgoing calls
no test coverage detected