add find operators

This commit is contained in:
Unknown 2018-06-13 02:29:32 +02:00
parent 38a59b921e
commit f9bb652034
3 changed files with 52 additions and 2 deletions

View File

@ -2,7 +2,7 @@ import logging
import warnings import warnings
import threading import threading
from sqlalchemy.sql import and_, expression from sqlalchemy.sql import and_, between, expression
from sqlalchemy.sql.expression import ClauseElement from sqlalchemy.sql.expression import ClauseElement
from sqlalchemy.schema import Column, Index from sqlalchemy.schema import Column, Index
from sqlalchemy import func, select, false from sqlalchemy import func, select, false
@ -293,6 +293,24 @@ class Table(object):
clauses.append(false()) clauses.append(false())
elif isinstance(value, (list, tuple)): elif isinstance(value, (list, tuple)):
clauses.append(self.table.c[column].in_(value)) 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: else:
clauses.append(self.table.c[column] == value) clauses.append(self.table.c[column] == value)
return and_(*clauses) return and_(*clauses)

View File

@ -138,9 +138,25 @@ We can search for specific entries using :py:meth:`find() <dataset.Table.find>`
# Get a specific user # Get a specific user
john = table.find_one(name='John Doe') 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) elderly_users = table.find(table.table.columns.age >= 70)
Possible comparison operators::
gt, >
lt, <
gte, >=
lte, <=
!=, <>, not
between, ..
Using :py:meth:`distinct() <dataset.Table.distinct>` we can grab a set of rows Using :py:meth:`distinct() <dataset.Table.distinct>` we can grab a set of rows
with unique values in one or more columns:: with unique values in one or more columns::

View File

@ -321,6 +321,22 @@ class TableTestCase(unittest.TestCase):
ds = list(self.tbl.find(self.tbl.table.columns.temperature > 4)) ds = list(self.tbl.find(self.tbl.table.columns.temperature > 4))
assert len(ds) == 3, ds 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): def test_offset(self):
ds = list(self.tbl.find(place=TEST_CITY_1, _offset=1)) ds = list(self.tbl.find(place=TEST_CITY_1, _offset=1))
assert len(ds) == 2, ds assert len(ds) == 2, ds