|
4 | 4 | from morango.models.core import Store |
5 | 5 |
|
6 | 6 | from .base import BaseSQLWrapper |
7 | | -from .utils import calculate_max_sqlite_variables |
8 | | -from .utils import get_pk_field |
9 | 7 |
|
10 | 8 |
|
11 | 9 | class SQLWrapper(BaseSQLWrapper): |
12 | 10 | backend = "sqlite" |
13 | 11 |
|
14 | | - def _bulk_full_record_upsert(self, cursor, table_name, fields, db_values): |
15 | | - """ |
16 | | - Example query: |
17 | | - `REPLACE INTO model (F1,F2,F3) VALUES (%s, %s, %s), (%s, %s, %s), (%s, %s, %s)` |
18 | | - where values=[1,2,3,4,5,6,7,8,9] |
19 | | - """ |
20 | | - placeholder_list = self._create_placeholder_list(fields, db_values) |
21 | | - # calculate and create equal sized chunks of data to insert incrementally |
22 | | - num_of_rows_able_to_insert = calculate_max_sqlite_variables() // len(fields) |
23 | | - num_of_values_able_to_insert = num_of_rows_able_to_insert * len(fields) |
24 | | - value_chunks = [ |
25 | | - db_values[x : x + num_of_values_able_to_insert] |
26 | | - for x in range(0, len(db_values), num_of_values_able_to_insert) |
27 | | - ] |
28 | | - placeholder_chunks = [ |
29 | | - placeholder_list[x : x + num_of_rows_able_to_insert] |
30 | | - for x in range(0, len(placeholder_list), num_of_rows_able_to_insert) |
31 | | - ] |
32 | | - # insert data chunks |
33 | | - fields_str = str(tuple(str(f.attname) for f in fields)).replace("'", "") |
34 | | - for values, params in zip(value_chunks, placeholder_chunks): |
35 | | - placeholder_str = ", ".join(params).replace("'", "") |
36 | | - insert = """ |
37 | | - REPLACE INTO {table_name} {fields} |
38 | | - VALUES {placeholder_str} |
39 | | - """.format( |
40 | | - table_name=table_name, |
41 | | - fields=fields_str, |
42 | | - placeholder_str=placeholder_str, |
43 | | - ) |
44 | | - # use DB-APIs parameter substitution (2nd parameter expects a sequence) |
45 | | - cursor.execute(insert, values) |
46 | | - |
47 | | - def _bulk_insert(self, cursor, table_name, fields, db_values): |
48 | | - num_of_rows_able_to_insert = calculate_max_sqlite_variables() // len(fields) |
49 | | - num_of_values_able_to_insert = num_of_rows_able_to_insert * len(fields) |
50 | | - value_chunks = [ |
51 | | - db_values[x : x + num_of_values_able_to_insert] |
52 | | - for x in range(0, len(db_values), num_of_values_able_to_insert) |
53 | | - ] |
54 | | - for value_chunk in value_chunks: |
55 | | - super(SQLWrapper, self)._bulk_insert(cursor, table_name, fields, value_chunk) |
56 | | - |
57 | | - def _bulk_update(self, cursor, table_name, fields, db_values): |
58 | | - """ |
59 | | - Example query: |
60 | | - `UPDATE model SET F1=(CASE id WHEN %s THEN %s ... END) ...` |
61 | | - WHERE id IN [...] |
62 | | - """ |
63 | | - # calculate and create equal sized chunks of data to update incrementally |
64 | | - # for every field we're updating, we'll require 3 parameters |
65 | | - num_update_fields = len(fields) - 1 |
66 | | - num_of_rows_able_to_update = calculate_max_sqlite_variables() // num_update_fields // 3 |
67 | | - num_of_values_able_to_update = num_of_rows_able_to_update * len(fields) |
68 | | - value_chunks = [ |
69 | | - db_values[x : x + num_of_values_able_to_update] |
70 | | - for x in range(0, len(db_values), num_of_values_able_to_update) |
71 | | - ] |
72 | | - pk = get_pk_field(fields) |
73 | | - |
74 | | - # insert data chunks |
75 | | - for values in value_chunks: |
76 | | - set_sql = "" |
77 | | - params = [] |
78 | | - pk_params = [] |
79 | | - for field in fields: |
80 | | - if field == pk: |
81 | | - continue |
82 | | - set_field_sql = " {field} = (CASE {pk_field}".format( |
83 | | - field=field.column, pk_field=pk.column |
84 | | - ) |
85 | | - for y in range(0, len(values), len(fields)): |
86 | | - value_set = values[y : y + len(fields)] |
87 | | - set_field_sql += " WHEN %s THEN %s" |
88 | | - pk_params.append(value_set[fields.index(pk)]) |
89 | | - params.append(value_set[fields.index(pk)]) |
90 | | - params.append(value_set[fields.index(field)]) |
91 | | - set_field_sql += " END)," |
92 | | - set_sql += set_field_sql |
93 | | - params.extend(pk_params) |
94 | | - update = """ |
95 | | - UPDATE {table_name} SET {set_sql} WHERE {pk_field} IN {placeholder_str} |
96 | | - """.format( |
97 | | - table_name=table_name, |
98 | | - set_sql=set_sql[:-1], |
99 | | - pk_field=pk.column, |
100 | | - placeholder_str="({})".format(",".join("%s" for _ in range(len(pk_params)))), |
101 | | - ) |
102 | | - # use DB-APIs parameter substitution (2nd parameter expects a sequence) |
103 | | - cursor.execute(update, params) |
104 | | - |
105 | 12 | def _dequeuing_merge_conflict_rmcb(self, cursor, transfersession_id): |
106 | 13 | # transfer record max counters for records with merge conflicts + perform max |
107 | 14 | merge_conflict_rmc = """REPLACE INTO {rmc} (instance_id, counter, store_model_id) |
|
0 commit comments