Пример #1
0
 def test_cume_dist(self):
     query = Query().from_table(
         table=Order,
         fields=[
             '*',
             CumeDistField(over=QueryWindow().order_by('-margin'))
         ]).order_by('cume_dist')
     query_str = query.get_sql()
     expected_query = (
         'SELECT tests_order.*, '
         'CUME_DIST() OVER (ORDER BY margin DESC) AS cume_dist '
         'FROM tests_order '
         'ORDER BY cume_dist '
         'ASC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
 def test_select_fields_same_two_tables(self):
     query = Query().from_table(
         table=Account,
         fields=['field_one', 'field_two'
                 ]).from_table(table=Account,
                               fields=['field_three', 'field_four'])
     query_str = query.get_sql()
     expected_query = (
         'SELECT querybuilder_tests_account.field_one, '
         'querybuilder_tests_account.field_two, '
         'T1.field_three, '
         'T1.field_four '
         'FROM querybuilder_tests_account, querybuilder_tests_account AS T1'
     )
     self.assertEqual(query_str, expected_query,
                      '\n{0}\n!=\n{1}'.format(query_str, expected_query))
 def test_select_sql_args(self):
     sql = 'SELECT id FROM querybuilder_tests_account WHERE id = %(my_id)s'
     sql_args = {
         'my_id': 2
     }
     rows = Query().select(sql=sql, sql_args=sql_args)
     received = rows[0]['id']
     expected = User.objects.all().filter(id=2)[0].id
     self.assertEqual(
         received,
         expected,
         'Expected {0} but received {1}'.format(
             expected,
             received
         )
     )
 def test_minute_auto(self):
     query = Query().from_table(table=Order,
                                fields=[Minute('time', auto=True)])
     query_str = query.get_sql()
     expected_query = (
         'SELECT CAST(EXTRACT(year FROM querybuilder_tests_order.time) AS INT) AS "time__year", '
         'CAST(EXTRACT(month FROM querybuilder_tests_order.time) AS INT) AS "time__month", '
         'CAST(EXTRACT(day FROM querybuilder_tests_order.time) AS INT) AS "time__day", '
         'CAST(EXTRACT(hour FROM querybuilder_tests_order.time) AS INT) AS "time__hour", '
         'CAST(EXTRACT(minute FROM querybuilder_tests_order.time) AS INT) AS "time__minute", '
         'CAST(EXTRACT(epoch FROM date_trunc(\'minute\', querybuilder_tests_order.time)) AS INT) AS "time__epoch" '
         'FROM querybuilder_tests_order '
         'GROUP BY time__year, time__month, time__day, time__hour, time__minute, time__epoch '
         'ORDER BY time__epoch ASC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
Пример #5
0
 def date_part_field_test(self):
     """
     Tests the different options of DatePartField objects
     """
     # test with no cast
     query = Query().from_table(
         table=Order, fields=[AllTime('time'),
                              SumField('margin')])
     expected_query = ('SELECT CAST(0 AS INT) AS "time__epoch", '
                       'SUM(tests_order.margin) AS "margin_sum" '
                       'FROM tests_order')
     self.assertEqual(expected_query, query.get_sql())
     rows = query.select()
     self.assertEqual(1, len(rows))
     self.assertEqual(825.0, rows[0]['margin_sum'])
     self.assertEqual(0, rows[0]['time__epoch'])
    def test_clear_log_no_index(self):
        """
        Makes sure that the query index doesn't change
        """
        logger_one = Logger('one')

        query = Query().from_table(Account)
        query.select()

        self.assertIsNone(logger_one.query_index)

        # clear the log
        logger_one.clear_log()

        # make sure no query index
        self.assertIsNone(logger_one.query_index)
 def test_nth_value(self):
     query = Query().from_table(
         table=Order,
         fields=[
             '*',
             NthValueField('margin',
                           n=2,
                           over=QueryWindow().order_by('-margin'))
         ])
     query_str = query.get_sql()
     expected_query = (
         'SELECT querybuilder_tests_order.*, '
         'NTH_VALUE(querybuilder_tests_order.margin, 2) OVER (ORDER BY margin DESC) AS "margin_nth_value" '
         'FROM querybuilder_tests_order')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
 def test_row_number(self):
     query = Query().from_table(
         table=Order,
         fields=[
             '*',
             RowNumberField(over=QueryWindow().order_by('-margin'))
         ]).order_by('row_number')
     query_str = query.get_sql()
     expected_query = (
         'SELECT querybuilder_tests_order.*, '
         'ROW_NUMBER() OVER (ORDER BY margin DESC) AS "row_number" '
         'FROM querybuilder_tests_order '
         'ORDER BY row_number '
         'ASC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
 def test_lag_default(self):
     query = Query().from_table(
         table=Order,
         fields=[
             '*',
             LagField('margin',
                      default=0,
                      over=QueryWindow().order_by('-margin'))
         ])
     query_str = query.get_sql()
     expected_query = (
         'SELECT querybuilder_tests_order.*, '
         'LAG(querybuilder_tests_order.margin, 1, \'0\') OVER (ORDER BY margin DESC) AS "margin_lag" '
         'FROM querybuilder_tests_order')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
 def test_ntile(self):
     query = Query().from_table(
         table=Order,
         fields=[
             '*',
             NTileField(num_buckets=2,
                        over=QueryWindow().order_by('-margin'))
         ]).order_by('ntile')
     query_str = query.get_sql()
     expected_query = ('SELECT querybuilder_tests_order.*, '
                       'NTILE(2) OVER (ORDER BY margin DESC) AS "ntile" '
                       'FROM querybuilder_tests_order '
                       'ORDER BY ntile '
                       'ASC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
Пример #11
0
 def test_rank_percent(self):
     query = Query().from_table(
         table=Order,
         fields=[
             '*',
             PercentRankField(over=QueryWindow().order_by('-margin'))
         ]).order_by('percent_rank')
     query_str = query.get_sql()
     expected_query = (
         'SELECT tests_order.*, '
         'PERCENT_RANK() OVER (ORDER BY margin DESC) AS percent_rank '
         'FROM tests_order '
         'ORDER BY percent_rank '
         'ASC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
Пример #12
0
 def test_dense_rank(self):
     query = Query().from_table(
         table=Order,
         fields=[
             '*',
             DenseRankField(over=QueryWindow().order_by('-margin'))
         ]).order_by('dense_rank')
     query_str = query.get_sql()
     expected_query = (
         'SELECT tests_order.*, '
         'DENSE_RANK() OVER (ORDER BY margin DESC) AS dense_rank '
         'FROM tests_order '
         'ORDER BY dense_rank '
         'ASC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
Пример #13
0
 def test_rank(self):
     query = Query().from_table(
         table=Order,
         fields=[
             'id',
             RankField(over=QueryWindow().partition_by(
                 'account_id').order_by('id'))
         ]).order_by('-rank')
     query_str = query.get_sql()
     expected_query = (
         'SELECT tests_order.id, '
         'RANK() OVER (PARTITION BY account_id ORDER BY id ASC) AS rank '
         'FROM tests_order '
         'ORDER BY rank '
         'DESC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
    def test_where_complex(self):
        query = Query().from_table(table='test_table').where(Q(one=1)).where(
            Q(two__gt=2)).where(~Q(three__gte=3)).where(
                ~Q(four__lt=4), OR).where(Q(five__lte=5), OR).where(
                    Q(six__contains='six')).where(~Q(
                        seven__startswith='seven')).where(
                            Q(eight=8) & Q(nine=9) | Q(ten=10) | ~Q(eleven=11))

        query_str = query.get_sql()
        expected_query = ''.join([
            'SELECT test_table.* FROM test_table WHERE ',
            '(((one = %(A0)s AND two > %(A1)s AND (NOT(three >= %(A2)s))) OR (NOT(four < %(A3)s)) ',
            'OR five <= %(A4)s) AND (six LIKE %(A5)s) AND (NOT(seven LIKE %(A6)s)) AND ',
            '((eight = %(A7)s AND nine = %(A8)s) OR ten = %(A9)s OR (NOT(eleven = %(A10)s))))'
        ])
        self.assertEqual(query_str, expected_query,
                         get_comparison_str(query_str, expected_query))
Пример #15
0
    def test_join_model_fields_prefix(self):
        query = Query().from_table(table=Account, fields=[
            '*',
        ]).join(Order, fields=[
            'id',
            'margin',
        ], prefix_fields=True)

        query_str = query.get_sql()

        expected_query = (
            'SELECT tests_account.*, '
            'tests_order.id AS "order__id", '
            'tests_order.margin AS "order__margin" '
            'FROM tests_account '
            'JOIN tests_order ON tests_order.account_id = tests_account.id')
        self.assertEqual(query_str, expected_query)
Пример #16
0
 def test_second_auto(self):
     query = Query().from_table(table=Order,
                                fields=[Second('time', auto=True)])
     query_str = query.get_sql()
     expected_query = (
         'SELECT CAST(EXTRACT(year FROM tests_order.time) AS INT) AS time__year, '
         'CAST(EXTRACT(month FROM tests_order.time) AS INT) AS time__month, '
         'CAST(EXTRACT(day FROM tests_order.time) AS INT) AS time__day, '
         'CAST(EXTRACT(hour FROM tests_order.time) AS INT) AS time__hour, '
         'CAST(EXTRACT(minute FROM tests_order.time) AS INT) AS time__minute, '
         'CAST(EXTRACT(second FROM tests_order.time) AS INT) AS time__second, '
         'CAST(EXTRACT(epoch FROM date_trunc(\'second\', tests_order.time)) AS INT) AS time__epoch '
         'FROM tests_order '
         'GROUP BY time__year, time__month, time__day, time__hour, time__minute, time__second, time__epoch '
         'ORDER BY time__epoch ASC')
     self.assertEqual(query_str, expected_query,
                      get_comparison_str(query_str, expected_query))
Пример #17
0
def bulk_update(manager, model_objs, fields_to_update):
    """
    Bulk updates a list of model objects that are already saved.

    Args:
        model_objs: A list of model objects that have been updated.
        fields_to_update: A list of fields to be updated. Only these fields will be updated

    Sianals: Emits a post_bulk_operation signal when completed.

    Examples:
        # Create a couple test models
        model_obj1 = TestModel.objects.create(int_field=1, float_field=2.0, char_field='Hi')
        model_obj2 = TestModel.objects.create(int_field=3, float_field=4.0, char_field='Hello')

        # Change their fields and do a bulk update
        model_obj1.int_field = 10
        model_obj1.float_field = 20.0
        model_obj2.int_field = 30
        model_obj2.float_field = 40.0
        bulk_update(TestModel.objects, [model_obj1, model_obj2], ['int_field', 'float_field'])

        # Reload the models and view their changes
        model_obj1 = TestModel.objects.get(id=model_obj1.id)
        print model_obj1.int_field, model_obj1.float_field
        10, 20.0

        model_obj2 = TestModel.objects.get(id=model_obj2.id)
        print model_obj2.int_field, model_obj2.float_field
        10, 20.0
    """
    updated_rows = [
        [model_obj.id] + [getattr(model_obj, field_name) for field_name in fields_to_update]
        for model_obj in model_objs
    ]
    if len(updated_rows) == 0 or len(fields_to_update) == 0:
        return

    # Execute the bulk update
    Query().from_table(
        table=manager.model,
        fields=chain(['id'] + fields_to_update),
    ).update(updated_rows)

    post_bulk_operation.send(sender=manager, model=manager.model)
Пример #18
0
    def test_where_and_with_not_combined_or(self):
        query = Query().from_table(
            table='test_table'
        ).where(Q(
            one='two'
        )).where(~Q(
            three='four'
        ) | Q(
            five='six'
        ))

        query_str = query.get_sql()
        expected_query = (
            'SELECT test_table.* '
            'FROM test_table '
            'WHERE (one = %(A0)s AND ((NOT(three = %(A1)s)) OR five = %(A2)s))'
        )
        self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
Пример #19
0
    def test_join_model_fields_extract(self):
        query = Query().from_table(table=Account, fields=[
            '*',
        ]).join(Order, fields=['*'])

        query_str = query.get_sql()
        expected_query = (
            'SELECT tests_account.*, '
            'tests_order.id, '
            'tests_order.account_id, '
            'tests_order.revenue, '
            'tests_order.margin, '
            'tests_order.margin_percent, '
            'tests_order.time '
            'FROM tests_account '
            'JOIN tests_order ON tests_order.account_id = tests_account.id')
        self.assertEqual(query_str, expected_query,
                         get_comparison_str(query_str, expected_query))
    def test_update_null_numbers(self):
        """
        Verifies that null values can be bulk updated
        """
        order1 = G(Order, revenue=10)
        order2 = G(Order, revenue=20)
        order3 = G(Order, revenue=30)
        query = Query().from_table(table=Order, fields=['id', 'revenue'])

        logger = Logger()
        logger.start_logging()
        rows = [[order1.id, None], [order2.id, None], [order3.id, 3000]]
        query.update(rows)

        orders = list(Order.objects.order_by('id'))
        self.assertIsNone(orders[0].revenue)
        self.assertIsNone(orders[1].revenue)
        self.assertEqual(3000, orders[2].revenue)
Пример #21
0
    def test_joined_model_foreign_reverse(self):
        query = Query().from_table(Order).join(right_table=Account,
                                               fields=['*'],
                                               prefix_fields=True)
        rows = query.select(True)

        self.assertGreater(len(rows), 0, 'No records')

        logger = Logger()
        logger.start_logging()
        for row in rows:
            self.assertIsInstance(row, Order, 'Record is not model instance')
            self.assertIs(hasattr(row, 'account'), True,
                          'Row does not have nested model')
            self.assertIsInstance(row.account, Account,
                                  'Nested record is not model instance')
        self.assertEqual(logger.count(), 0,
                         'Queries were executed when none should')
    def test_update_all_nulls(self):
        """
        Verifies that the sql is modified when all values for a field are null. For whatever reason,
        postgres doesn't handle this the same when all values are null
        """
        order1 = G(Order, revenue=10, margin=5)
        order2 = G(Order, revenue=20, margin=10)
        order3 = G(Order, revenue=30, margin=15)
        query = Query().from_table(table=Order, fields=['id', 'revenue', 'margin'])

        logger = Logger()
        logger.start_logging()
        rows = [[order1.id, None, 50], [order2.id, None, 100], [order3.id, None, 150]]
        query.update(rows)

        orders = list(Order.objects.order_by('id'))
        self.assertIsNone(orders[0].revenue)
        self.assertIsNone(orders[1].revenue)
        self.assertIsNone(orders[2].revenue)
Пример #23
0
    def test_find_field(self):
        query = Query().from_table(
            table=Account,
            extract_fields=True,
        ).from_table(table={
            'account2': Account
        },
                     fields=[{
                         'name': 'first_name'
                     }]).join(Order)

        table = query.tables[0]
        field = table.find_field('id')
        self.assertIsNotNone(field, 'Field not found')

        result = field.get_identifier()
        expected = 'tests_account.id'
        self.assertEqual(result, expected,
                         get_comparison_str(result, expected))
Пример #24
0
    def test_join_model_fields(self):
        query = Query().from_table(table=Account, fields=[
            'one',
            'two',
        ]).join(Order, fields=[{
            'three': 'one'
        }, {
            'four': 'two'
        }])

        query_str = query.get_sql()
        expected_query = (
            'SELECT tests_account.one, '
            'tests_account.two, '
            'tests_order.one AS "three", '
            'tests_order.two AS "four" '
            'FROM tests_account '
            'JOIN tests_order ON tests_order.account_id = tests_account.id')
        self.assertEqual(query_str, expected_query,
                         get_comparison_str(query_str, expected_query))
Пример #25
0
    def test_upsert_json_field(self):
        """
        Only runs for django 1.9 because the jsonfield project uses an incorrect db prep value
        """
        if VERSION[0] != 1 or VERSION[1] < 9:
            return

        items = [
            Uniques(field1='1.1',
                    field2='1.2',
                    field3='1.3',
                    field6='1.6',
                    field7='1.7',
                    field8={'one': 'two'}),
        ]

        Query().from_table(Uniques).upsert(
            items,
            unique_fields=['field1'],
            update_fields=['field3', 'field4', 'field5', 'field8'])
    def test_stop_logging(self):
        """
        Verifies that the logger stops caring about queries
        """
        logger = Logger()
        logger.start_logging()

        query = Query().from_table(Account)
        query.select()
        query.select()

        self.assertEqual(2, logger.count())

        logger.stop_logging()
        query.select()
        query.select()
        self.assertEqual(2, logger.count())

        logger.start_logging()
        query.select()
        self.assertEqual(3, logger.count())
    def test_upsert_pk(self):
        """
        Makes sure upserting is possible when the only uniqueness constraint is the pk.
        """
        user1 = G(User, email='user1')
        user1.email = 'user1change'
        user2 = User(email='user2')
        user3 = User(email='user3')

        self.assertEqual(User.objects.count(), 1)
        Query().from_table(User).upsert(
            [user1, user2, user3],
            unique_fields=['id'],
            update_fields=['email'],
        )
        self.assertEqual(User.objects.count(), 3)

        users = list(User.objects.order_by('id'))

        self.assertEqual(users[0].email, 'user1change')
        self.assertEqual(users[1].email, 'user2')
        self.assertEqual(users[2].email, 'user3')
    def test_no_fields_and_fields(self):
        query = Query().from_table(
            table=Account,
            fields=None
        ).join(
            'other_table',
            fields=[
                'field_one',
                'field_two'
            ],
            prefix_fields=True,
            condition='other_table.test_id = tests_account.id'
        )

        query_str = query.get_sql()
        expected_query = (
            'SELECT other_table.field_one AS other_table__field_one, '
            'other_table.field_two AS other_table__field_two '
            'FROM tests_account '
            'JOIN other_table ON other_table.test_id = tests_account.id'
        )
        self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
    def test_join_model_fields_all(self):
        query = Query().from_table(
            table=Account,
            fields=[
                '*',
            ]
        ).join(
            Order,
            fields=[
                '*'
            ],
            extract_fields=False
        )

        query_str = query.get_sql()
        expected_query = (
            'SELECT tests_account.*, '
            'tests_order.* '
            'FROM tests_account '
            'JOIN tests_order ON tests_order.account_id = tests_account.id'
        )
        self.assertEqual(query_str, expected_query, get_comparison_str(query_str, expected_query))
Пример #30
0
    def test_num_stddev(self):
        query = Query().from_table(table=Order,
                                   fields=[
                                       '*',
                                       NumStdDevField('margin',
                                                      over=QueryWindow())
                                   ]).order_by('-margin_num_stddev')

        query_str = query.get_sql()
        expected_query = (
            'SELECT tests_order.*, '
            '(CASE WHEN (STDDEV(tests_order.margin) OVER ()) <> 0 '
            'THEN ((tests_order.margin - ('
            'AVG(tests_order.margin) OVER ())) / (STDDEV(tests_order.margin) OVER ())) '
            'ELSE 0 '
            'END) '
            'AS margin_num_stddev '
            'FROM tests_order '
            'ORDER BY margin_num_stddev '
            'DESC')
        self.assertEqual(query_str, expected_query,
                         get_comparison_str(query_str, expected_query))