From f9bb652034bc7a85446064f32efb558eab9b90d8 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 13 Jun 2018 02:29:32 +0200 Subject: [PATCH 1/5] add find operators --- dataset/table.py | 20 +++++++++++++++++++- docs/quickstart.rst | 18 +++++++++++++++++- test/test_dataset.py | 16 ++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/dataset/table.py b/dataset/table.py index e59dbb2..bab202a 100644 --- a/dataset/table.py +++ b/dataset/table.py @@ -2,7 +2,7 @@ import logging import warnings import threading -from sqlalchemy.sql import and_, expression +from sqlalchemy.sql import and_, between, expression from sqlalchemy.sql.expression import ClauseElement from sqlalchemy.schema import Column, Index from sqlalchemy import func, select, false @@ -293,6 +293,24 @@ class Table(object): clauses.append(false()) elif isinstance(value, (list, tuple)): clauses.append(self.table.c[column].in_(value)) + elif isinstance(value, dict): + key = list(value.keys())[0] + if key in ['like']: + clauses.append(self.table.c[column].like(value[key])) + elif key in ['>', 'gt']: + clauses.append(self.table.c[column] > value[key]) + elif key in ['<', 'lt']: + clauses.append(self.table.c[column] < value[key]) + elif key in ['>=', 'gte']: + clauses.append(self.table.c[column] >= value[key]) + elif key in ['<=', 'lte']: + clauses.append(self.table.c[column] <= value[key]) + elif key in ['!=', '<>', 'not']: + clauses.append(self.table.c[column] != value[key]) + elif key in ['between', '..']: + clauses.append(self.table.c[column].between(value[key][0], value[key][1])) + else: + clauses.append(false) else: clauses.append(self.table.c[column] == value) return and_(*clauses) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 72114cf..5edcc17 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -138,9 +138,25 @@ We can search for specific entries using :py:meth:`find() ` # Get a specific user john = table.find_one(name='John Doe') - # Find by comparison + # Find multiple at once + winners = table.find(id=[1, 3, 7]) + + # Find by comparison operator + elderly_users = table.find(age={'>=', 70}) + possible_customers = table.find(age={'between', [21, 80]}) + + # Use the underlying SQLAlchemy directly elderly_users = table.find(table.table.columns.age >= 70) +Possible comparison operators:: + + gt, > + lt, < + gte, >= + lte, <= + !=, <>, not + between, .. + Using :py:meth:`distinct() ` we can grab a set of rows with unique values in one or more columns:: diff --git a/test/test_dataset.py b/test/test_dataset.py index b9d046c..4cd0645 100644 --- a/test/test_dataset.py +++ b/test/test_dataset.py @@ -321,6 +321,22 @@ class TableTestCase(unittest.TestCase): ds = list(self.tbl.find(self.tbl.table.columns.temperature > 4)) assert len(ds) == 3, ds + def test_find_dsl(self): + ds = list(self.tbl.find(place={'like': '%lw%'})) + assert len(ds) == 3, ds + ds = list(self.tbl.find(temperature={'>': 5})) + assert len(ds) == 2, ds + ds = list(self.tbl.find(temperature={'>=': 5})) + assert len(ds) == 3, ds + ds = list(self.tbl.find(temperature={'<': 0})) + assert len(ds) == 1, ds + ds = list(self.tbl.find(temperature={'<=': 0})) + assert len(ds) == 2, ds + ds = list(self.tbl.find(temperature={'!=': -1})) + assert len(ds) == 5, ds + ds = list(self.tbl.find(temperature={'between': [5, 8]})) + assert len(ds) == 3, ds + def test_offset(self): ds = list(self.tbl.find(place=TEST_CITY_1, _offset=1)) assert len(ds) == 2, ds From 5829fcc366cdf0a33afcab32ee3898afd0e8d501 Mon Sep 17 00:00:00 2001 From: Unknown Date: Wed, 13 Jun 2018 03:35:24 +0200 Subject: [PATCH 2/5] remove unused between import --- dataset/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataset/table.py b/dataset/table.py index bab202a..c4c944d 100644 --- a/dataset/table.py +++ b/dataset/table.py @@ -2,7 +2,7 @@ import logging import warnings import threading -from sqlalchemy.sql import and_, between, expression +from sqlalchemy.sql import and_, expression from sqlalchemy.sql.expression import ClauseElement from sqlalchemy.schema import Column, Index from sqlalchemy import func, select, false From 7746e2529b03c5c33ee54f0b15018515e96b57dc Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 14 Jun 2018 07:01:35 +0200 Subject: [PATCH 3/5] convert unchangeable lists to tuples --- dataset/table.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/dataset/table.py b/dataset/table.py index c4c944d..5f2449d 100644 --- a/dataset/table.py +++ b/dataset/table.py @@ -295,19 +295,19 @@ class Table(object): clauses.append(self.table.c[column].in_(value)) elif isinstance(value, dict): key = list(value.keys())[0] - if key in ['like']: + if key in ('like',): clauses.append(self.table.c[column].like(value[key])) - elif key in ['>', 'gt']: + elif key in ('>', 'gt'): clauses.append(self.table.c[column] > value[key]) - elif key in ['<', 'lt']: + elif key in ('<', 'lt'): clauses.append(self.table.c[column] < value[key]) - elif key in ['>=', 'gte']: + elif key in ('>=', 'gte'): clauses.append(self.table.c[column] >= value[key]) - elif key in ['<=', 'lte']: + elif key in ('<=', 'lte'): clauses.append(self.table.c[column] <= value[key]) - elif key in ['!=', '<>', 'not']: + elif key in ('!=', '<>', 'not'): clauses.append(self.table.c[column] != value[key]) - elif key in ['between', '..']: + elif key in ('between', '..'): clauses.append(self.table.c[column].between(value[key][0], value[key][1])) else: clauses.append(false) From f9a0f6de6066f61b8f5cb623d500196d672ce449 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 14 Jun 2018 07:02:45 +0200 Subject: [PATCH 4/5] change wrong usage of sets to dicts --- docs/quickstart.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/quickstart.rst b/docs/quickstart.rst index 5edcc17..66bd053 100644 --- a/docs/quickstart.rst +++ b/docs/quickstart.rst @@ -142,8 +142,8 @@ We can search for specific entries using :py:meth:`find() ` winners = table.find(id=[1, 3, 7]) # Find by comparison operator - elderly_users = table.find(age={'>=', 70}) - possible_customers = table.find(age={'between', [21, 80]}) + elderly_users = table.find(age={'>=': 70}) + possible_customers = table.find(age={'between': [21, 80]}) # Use the underlying SQLAlchemy directly elderly_users = table.find(table.table.columns.age >= 70) From 45e3ec003735b1c1ea721bd5aca53fdf7a7e2fa0 Mon Sep 17 00:00:00 2001 From: Unknown Date: Thu, 14 Jun 2018 07:03:38 +0200 Subject: [PATCH 5/5] fix wrong clauses parameter false to sqlalchemy's false() --- dataset/table.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataset/table.py b/dataset/table.py index 5f2449d..2bd5c55 100644 --- a/dataset/table.py +++ b/dataset/table.py @@ -310,7 +310,7 @@ class Table(object): elif key in ('between', '..'): clauses.append(self.table.c[column].between(value[key][0], value[key][1])) else: - clauses.append(false) + clauses.append(false()) else: clauses.append(self.table.c[column] == value) return and_(*clauses)