Skip to content

Commit 0c47cd1

Browse files
authored
Merge pull request #98 from ambitioninc/develop
1.2.0
2 parents b8c1fd4 + fd0c6e5 commit 0c47cd1

21 files changed

+360
-248
lines changed

.travis.yml

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,28 @@
1+
dist: xenial
12
language: python
2-
33
sudo: false
44

55
python:
6-
- "2.7"
7-
- "3.4"
8-
- "3.5"
96
- "3.6"
7+
- "3.7"
108

119
env:
1210
matrix:
13-
- DJANGO=1.10
14-
- DJANGO=1.11
1511
- DJANGO=2.0
12+
- DJANGO=2.1
13+
- DJANGO=2.2
1614
- DJANGO=master
1715

1816
addons:
19-
postgresql: '9.5'
17+
postgresql: '9.6'
2018

2119
matrix:
20+
exclude:
21+
- { python: "3.7", env: DJANGO=2.0 }
22+
2223
include:
2324
- { python: "3.6", env: TOXENV=flake8 }
2425

25-
exclude:
26-
- { python: "2.7", env: DJANGO=master }
27-
- { python: "2.7", env: DJANGO=2.0 }
28-
- { python: "3.4", env: DJANGO=master }
29-
- { python: "3.6", env: DJANGO=1.10 }
30-
3126
allow_failures:
3227
- env: DJANGO=master
3328

docs/release_notes.rst

+10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,16 @@
11
Release Notes
22
=============
33

4+
v1.2.0
5+
------
6+
* Add Django 2.1
7+
* Add Django 2.2
8+
* Add python 3.7
9+
* Drop python 2.7
10+
* Drop python 3.4
11+
* Drop python 3.5
12+
* Drop Django 1.10
13+
414
v1.1.0
515
------
616
* Use tox to support more versions

querybuilder/query.py

+27-8
Original file line numberDiff line numberDiff line change
@@ -173,8 +173,7 @@ def set_right_table(self, table):
173173
# check if this join type is for a foreign key
174174
for field in self.left_table.model._meta.fields:
175175
if (
176-
field.get_internal_type() == 'OneToOneField' or
177-
field.get_internal_type() == 'ForeignKey'
176+
field.get_internal_type() == 'OneToOneField' or field.get_internal_type() == 'ForeignKey'
178177
):
179178
if field.remote_field.model == self.right_table.model:
180179
if self.right_table.field_prefix is None:
@@ -213,8 +212,7 @@ def get_condition(self):
213212
# check if this join type is for a foreign key
214213
for field in self.right_table.model._meta.fields:
215214
if (
216-
field.get_internal_type() == 'OneToOneField' or
217-
field.get_internal_type() == 'ForeignKey'
215+
field.get_internal_type() == 'OneToOneField' or field.get_internal_type() == 'ForeignKey'
218216
):
219217
if field.remote_field.model == self.left_table.model:
220218
table_join_field = field.column
@@ -1159,11 +1157,32 @@ def get_update_sql(self, rows):
11591157
row_values = []
11601158
sql_args = []
11611159

1162-
for row in rows:
1160+
# Loop over each row and put the %s placeholder for each field
1161+
for i, row in enumerate(rows):
1162+
1163+
# Build a list of each field's placeholder
11631164
placeholders = []
1164-
for value in row:
1165-
sql_args.append(value)
1166-
placeholders.append('%s')
1165+
1166+
# If this is the first row, add casting information so the db knows the field types
1167+
if i == 0 and hasattr(self.tables[0], 'model'):
1168+
for field_index, value in enumerate(row):
1169+
# Append the value
1170+
sql_args.append(value)
1171+
1172+
# Figure out how to cast it
1173+
field_object = self.tables[0].model._meta.get_field(field_names[field_index])
1174+
db_type = field_object.db_type(self.connection)
1175+
1176+
# Don't cast the pk
1177+
if db_type == 'serial':
1178+
placeholders.append('%s')
1179+
else:
1180+
# Cast the placeholder to the data type
1181+
placeholders.append('%s::{0}'.format(db_type))
1182+
else:
1183+
for value in row:
1184+
sql_args.append(value)
1185+
placeholders.append('%s')
11671186
row_values.append('({0})'.format(', '.join(placeholders)))
11681187
row_values_sql = ', '.join(row_values)
11691188

querybuilder/tests/__init__.py

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
default_app_config = 'querybuilder.tests.apps.QuerybuilderTestConfig'

querybuilder/tests/aggregate_tests.py

+14-7
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ def test_avg(self):
5757
]
5858
)
5959
query_str = query.get_sql()
60-
expected_query = 'SELECT AVG(tests_order.margin) AS "margin_avg" FROM tests_order'
60+
expected_query = 'SELECT AVG(querybuilder_tests_order.margin) AS "margin_avg" FROM querybuilder_tests_order'
6161
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
6262

6363
def test_max_field(self):
@@ -71,7 +71,7 @@ def test_max_field(self):
7171
]
7272
)
7373
query_str = query.get_sql()
74-
expected_query = 'SELECT MAX(tests_order.margin) AS "margin_max" FROM tests_order'
74+
expected_query = 'SELECT MAX(querybuilder_tests_order.margin) AS "margin_max" FROM querybuilder_tests_order'
7575
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
7676

7777
def test_min_field(self):
@@ -85,7 +85,7 @@ def test_min_field(self):
8585
]
8686
)
8787
query_str = query.get_sql()
88-
expected_query = 'SELECT MIN(tests_order.margin) AS "margin_min" FROM tests_order'
88+
expected_query = 'SELECT MIN(querybuilder_tests_order.margin) AS "margin_min" FROM querybuilder_tests_order'
8989
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
9090

9191
def test_stddev(self):
@@ -96,7 +96,9 @@ def test_stddev(self):
9696
]
9797
)
9898
query_str = query.get_sql()
99-
expected_query = 'SELECT STDDEV(tests_order.margin) AS "margin_stddev" FROM tests_order'
99+
expected_query = (
100+
'SELECT STDDEV(querybuilder_tests_order.margin) AS "margin_stddev" FROM querybuilder_tests_order'
101+
)
100102
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
101103

102104
def test_sum_field(self):
@@ -110,7 +112,7 @@ def test_sum_field(self):
110112
]
111113
)
112114
query_str = query.get_sql()
113-
expected_query = 'SELECT SUM(tests_order.margin) AS "margin_sum" FROM tests_order'
115+
expected_query = 'SELECT SUM(querybuilder_tests_order.margin) AS "margin_sum" FROM querybuilder_tests_order'
114116
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
115117

116118
def test_variance(self):
@@ -121,7 +123,9 @@ def test_variance(self):
121123
]
122124
)
123125
query_str = query.get_sql()
124-
expected_query = 'SELECT VARIANCE(tests_order.margin) AS "margin_variance" FROM tests_order'
126+
expected_query = (
127+
'SELECT VARIANCE(querybuilder_tests_order.margin) AS "margin_variance" FROM querybuilder_tests_order'
128+
)
125129
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
126130

127131
def test_count(self):
@@ -139,7 +143,10 @@ def test_count(self):
139143
received
140144
)
141145
)
142-
self.assertEqual(query.get_count_query().get_sql(), 'SELECT COUNT(tests_user.*) AS "all_count" FROM tests_user')
146+
self.assertEqual(
147+
query.get_count_query().get_sql(),
148+
'SELECT COUNT(querybuilder_tests_user.*) AS "all_count" FROM querybuilder_tests_user'
149+
)
143150

144151
# Make sure the copy didn't modify the original
145152
self.assertEqual(len(query.tables[0].fields), 2)

querybuilder/tests/apps.py

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
from django.apps import AppConfig
2+
3+
4+
class QuerybuilderTestConfig(AppConfig):
5+
name = 'querybuilder.tests'
6+
label = 'querybuilder_tests'
7+
verbose_name = 'querybuilder Tests'

querybuilder/tests/date_tests.py

+38-35
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,10 @@ def test_year(self):
1313
]
1414
)
1515
query_str = query.get_sql()
16-
expected_query = 'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS "time__year" FROM tests_order'
16+
expected_query = (
17+
'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year" '
18+
'FROM querybuilder_tests_order'
19+
)
1720
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
1821

1922
def test_year_auto(self):
@@ -25,9 +28,9 @@ def test_year_auto(self):
2528
)
2629
query_str = query.get_sql()
2730
expected_query = (
28-
'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS "time__year", '
29-
'CAST(EXTRACT(epoch FROM date_trunc(\'year\', tests_order.time)) AS INT) AS "time__epoch" '
30-
'FROM tests_order '
31+
'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year", '
32+
'CAST(EXTRACT(epoch FROM date_trunc(\'year\', querybuilder_tests_order.time)) AS INT) AS "time__epoch" '
33+
'FROM querybuilder_tests_order '
3134
'GROUP BY time__year, time__epoch '
3235
'ORDER BY time__epoch ASC'
3336
)
@@ -42,9 +45,9 @@ def test_year_auto_desc(self):
4245
)
4346
query_str = query.get_sql()
4447
expected_query = (
45-
'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS "time__year", '
46-
'CAST(EXTRACT(epoch FROM date_trunc(\'year\', tests_order.time)) AS INT) AS "time__epoch" '
47-
'FROM tests_order '
48+
'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year", '
49+
'CAST(EXTRACT(epoch FROM date_trunc(\'year\', querybuilder_tests_order.time)) AS INT) AS "time__epoch" '
50+
'FROM querybuilder_tests_order '
4851
'GROUP BY time__year, time__epoch '
4952
'ORDER BY time__epoch DESC'
5053
)
@@ -59,10 +62,10 @@ def test_month_auto(self):
5962
)
6063
query_str = query.get_sql()
6164
expected_query = (
62-
'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS "time__year", '
63-
'CAST(EXTRACT(month FROM tests_order.time) AS INT) AS "time__month", '
64-
'CAST(EXTRACT(epoch FROM date_trunc(\'month\', tests_order.time)) AS INT) AS "time__epoch" '
65-
'FROM tests_order '
65+
'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year", '
66+
'CAST(EXTRACT(month FROM querybuilder_tests_order.time) AS INT) AS "time__month", '
67+
'CAST(EXTRACT(epoch FROM date_trunc(\'month\', querybuilder_tests_order.time)) AS INT) AS "time__epoch" '
68+
'FROM querybuilder_tests_order '
6669
'GROUP BY time__year, time__month, time__epoch '
6770
'ORDER BY time__epoch ASC'
6871
)
@@ -77,12 +80,12 @@ def test_hour_auto(self):
7780
)
7881
query_str = query.get_sql()
7982
expected_query = (
80-
'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS "time__year", '
81-
'CAST(EXTRACT(month FROM tests_order.time) AS INT) AS "time__month", '
82-
'CAST(EXTRACT(day FROM tests_order.time) AS INT) AS "time__day", '
83-
'CAST(EXTRACT(hour FROM tests_order.time) AS INT) AS "time__hour", '
84-
'CAST(EXTRACT(epoch FROM date_trunc(\'hour\', tests_order.time)) AS INT) AS "time__epoch" '
85-
'FROM tests_order '
83+
'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year", '
84+
'CAST(EXTRACT(month FROM querybuilder_tests_order.time) AS INT) AS "time__month", '
85+
'CAST(EXTRACT(day FROM querybuilder_tests_order.time) AS INT) AS "time__day", '
86+
'CAST(EXTRACT(hour FROM querybuilder_tests_order.time) AS INT) AS "time__hour", '
87+
'CAST(EXTRACT(epoch FROM date_trunc(\'hour\', querybuilder_tests_order.time)) AS INT) AS "time__epoch" '
88+
'FROM querybuilder_tests_order '
8689
'GROUP BY time__year, time__month, time__day, time__hour, time__epoch '
8790
'ORDER BY time__epoch ASC'
8891
)
@@ -97,13 +100,13 @@ def test_minute_auto(self):
97100
)
98101
query_str = query.get_sql()
99102
expected_query = (
100-
'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS "time__year", '
101-
'CAST(EXTRACT(month FROM tests_order.time) AS INT) AS "time__month", '
102-
'CAST(EXTRACT(day FROM tests_order.time) AS INT) AS "time__day", '
103-
'CAST(EXTRACT(hour FROM tests_order.time) AS INT) AS "time__hour", '
104-
'CAST(EXTRACT(minute FROM tests_order.time) AS INT) AS "time__minute", '
105-
'CAST(EXTRACT(epoch FROM date_trunc(\'minute\', tests_order.time)) AS INT) AS "time__epoch" '
106-
'FROM tests_order '
103+
'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year", '
104+
'CAST(EXTRACT(month FROM querybuilder_tests_order.time) AS INT) AS "time__month", '
105+
'CAST(EXTRACT(day FROM querybuilder_tests_order.time) AS INT) AS "time__day", '
106+
'CAST(EXTRACT(hour FROM querybuilder_tests_order.time) AS INT) AS "time__hour", '
107+
'CAST(EXTRACT(minute FROM querybuilder_tests_order.time) AS INT) AS "time__minute", '
108+
'CAST(EXTRACT(epoch FROM date_trunc(\'minute\', querybuilder_tests_order.time)) AS INT) AS "time__epoch" '
109+
'FROM querybuilder_tests_order '
107110
'GROUP BY time__year, time__month, time__day, time__hour, time__minute, time__epoch '
108111
'ORDER BY time__epoch ASC'
109112
)
@@ -118,14 +121,14 @@ def test_second_auto(self):
118121
)
119122
query_str = query.get_sql()
120123
expected_query = (
121-
'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS "time__year", '
122-
'CAST(EXTRACT(month FROM tests_order.time) AS INT) AS "time__month", '
123-
'CAST(EXTRACT(day FROM tests_order.time) AS INT) AS "time__day", '
124-
'CAST(EXTRACT(hour FROM tests_order.time) AS INT) AS "time__hour", '
125-
'CAST(EXTRACT(minute FROM tests_order.time) AS INT) AS "time__minute", '
126-
'CAST(EXTRACT(second FROM tests_order.time) AS INT) AS "time__second", '
127-
'CAST(EXTRACT(epoch FROM date_trunc(\'second\', tests_order.time)) AS INT) AS "time__epoch" '
128-
'FROM tests_order '
124+
'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year", '
125+
'CAST(EXTRACT(month FROM querybuilder_tests_order.time) AS INT) AS "time__month", '
126+
'CAST(EXTRACT(day FROM querybuilder_tests_order.time) AS INT) AS "time__day", '
127+
'CAST(EXTRACT(hour FROM querybuilder_tests_order.time) AS INT) AS "time__hour", '
128+
'CAST(EXTRACT(minute FROM querybuilder_tests_order.time) AS INT) AS "time__minute", '
129+
'CAST(EXTRACT(second FROM querybuilder_tests_order.time) AS INT) AS "time__second", '
130+
'CAST(EXTRACT(epoch FROM date_trunc(\'second\', querybuilder_tests_order.time)) AS INT) AS "time__epoch" '
131+
'FROM querybuilder_tests_order '
129132
'GROUP BY time__year, time__month, time__day, time__hour, time__minute, time__second, time__epoch '
130133
'ORDER BY time__epoch ASC'
131134
)
@@ -140,8 +143,8 @@ def test_group_none(self):
140143
)
141144
query_str = query.get_sql()
142145
expected_query = (
143-
'SELECT CAST(EXTRACT(epoch FROM tests_order.time) AS INT) AS "time__epoch" '
144-
'FROM tests_order '
146+
'SELECT CAST(EXTRACT(epoch FROM querybuilder_tests_order.time) AS INT) AS "time__epoch" '
147+
'FROM querybuilder_tests_order '
145148
'GROUP BY time__epoch '
146149
'ORDER BY time__epoch ASC'
147150
)
@@ -155,5 +158,5 @@ def test_group_all(self):
155158
]
156159
)
157160
query_str = query.get_sql()
158-
expected_query = 'SELECT CAST(0 AS INT) AS "time__epoch" FROM tests_order'
161+
expected_query = 'SELECT CAST(0 AS INT) AS "time__epoch" FROM querybuilder_tests_order'
159162
self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))

0 commit comments

Comments
 (0)