| 19 | |
| 20 | |
| 21 | class WikiSQL: |
| 22 | def __init__(self, dataset, save_dir="/tmp"): |
| 23 | valid_sets = ("train", "dev", "test") |
| 24 | if dataset not in valid_sets: |
| 25 | raise ValueError(f"Dataset must be in {valid_sets}, got {dataset}") |
| 26 | data_dir = os.path.join(save_dir, "wikisql") |
| 27 | self._maybe_download(data_dir) |
| 28 | |
| 29 | self._parse_tables(os.path.join(data_dir, f"data/{dataset}.tables.jsonl")) |
| 30 | self._parse_queries(os.path.join(data_dir, f"data/{dataset}.jsonl")) |
| 31 | |
| 32 | def _maybe_download(self, data_dir): |
| 33 | if not os.path.exists(data_dir): |
| 34 | import io |
| 35 | import tarfile |
| 36 | from urllib import request |
| 37 | |
| 38 | url = "https://raw.githubusercontent.com/salesforce/WikiSQL/master/data.tar.bz2" |
| 39 | r = request.urlopen(url) |
| 40 | with tarfile.open(fileobj=io.BytesIO(r.read())) as tf: |
| 41 | tf.extractall(data_dir) |
| 42 | |
| 43 | def _parse_tables(self, tables): |
| 44 | self._tables = {} |
| 45 | with open(tables) as f: |
| 46 | for line in f: |
| 47 | table = json.loads(line) |
| 48 | self._tables[table["id"]] = { |
| 49 | "columns": table["header"], |
| 50 | "types": table["types"], |
| 51 | "desc": f"table: {table['id']}\ncolumns: {', '.join(table['header'])}", |
| 52 | } |
| 53 | |
| 54 | def _parse_queries(self, queries): |
| 55 | self._queries = [] |
| 56 | with open(queries) as f: |
| 57 | for line in f: |
| 58 | query = json.loads(line) |
| 59 | table = self._tables[query["table_id"]] |
| 60 | question = query["question"] |
| 61 | answer = self.query_to_text( |
| 62 | query["sql"], query["table_id"], table["columns"], table["types"] |
| 63 | ) |
| 64 | self._queries.append( |
| 65 | f"<s>{table['desc']}\nQ: {question}\nA: {answer}</s>" |
| 66 | ) |
| 67 | |
| 68 | def query_to_text(self, query, table, columns, types): |
| 69 | aggregation_ops = ["", "MAX", "MIN", "COUNT", "SUM", "AVG"] |
| 70 | condition_ops = ["=", ">", "<", "OP"] |
| 71 | column = columns[query["sel"]] |
| 72 | aggregation = (aggregation_ops[query["agg"]] + " ") if query["agg"] > 0 else "" |
| 73 | sql = f"SELECT {aggregation}{column} FROM {table}" |
| 74 | |
| 75 | conditions = query["conds"] |
| 76 | if conditions: |
| 77 | cs = [] |
| 78 | for i, o, v in conditions: |
no outgoing calls
no test coverage detected