3. Find entities (Basic)¶
Previously, we added an entity. Now, we just need to find it properly.
However, just before we move onto the next step, let’s add more Player entities.
# Add more entities
repository.persist(Player('Ramza', 9))
repository.persist(Player('Tsunemori', 6))
repository.commit()
Find many entities without constrains¶
Suppose we want to retrieve everyone. There are two ways you can do it.
First, just invoke the find
method of repository
.
result = repository.find()
Or alternatively, you can create a new passerine.db.query.Query
via repository
.
query = repository.new_criteria('p')
result = repository.find(query)
You should then see the same output (result
) like the following:
[<Player {'level': 5, 'name': 'Sid', 'team': None}>, <Player {'level': 6, 'name': 'Tsunemori', 'team': None}>, <Player {'level': 9, 'name': 'Ramza', 'team': None}>]
Warning
passerine.db.query.Query
must always be instantiated via passerine.db.repository.Repository
.
Please do not try to instantiate the Query class directly.
Find many entities with constrains¶
Suppose we want to retrieve the information of the player named “Sid”. There are two ways you can do it.
Hand-coded expectation¶
First, just hand-code the expected value.
query = repository.new_criteria('p')
query.expect('p.name = "Sid"')
result = repository.find(query)
query = repository.new_criteria('p')
is to instantiate a query object (passerine.db.query.Query
) where
the alias of the expected entitiy is p
. Then, query.expect('p.name = "Sid"')
set the expectation that the
attribute name
of the expected entities must be equal to Sid
. result = repository.find(query)
will perform
the query with the specification defined in query
. If you execute the code, you should see the output (result
) like this:
[<Player {'level': 5, 'name': 'Sid', 'team': None}>]
Note
The syntax for the expectation is ironically similar to SQL and DQL (Doctrine Query Language). It is by design to generalize the interface between different types of drivers.
Parameterized expectation (exact match)¶
However, the previous query
is not reusable with the dynamic data. We will create the Query object with
parameters to allow use to reuse the same query object for different parameters.
query = repository.new_criteria('p')
query.expect('p.name = :name')
query.define('name', 'Sid')
result = repository.find(query)
In this snippet, you will see that in query.expect('p.name = :name')
, :name
replaces "Sid"
and
query.define('name', 'Sid')
defines the value of the parameter name
. This is equivalent to
query.expect('p.name = "Sid"')
as you will see the same output (result
):
[<Player {'level': 5, 'name': 'Sid', 'team': None}>]
However, without recreating the Query object, if I re-define the parameter name
with Tsunemori
by adding:
query.define('name', 'Tsunemori')
you will now get the different result:
[<Player {'level': 6, 'name': 'Tsunemori', 'team': None}>]
Note
This is the recommended way to query.
Range query¶
To do range search, just like the previous examples, you can either hand-code the expectation or rely on the parameterization. The following example uses the latter:
# Range-query multiple
query = repository.new_criteria('p')
query.expect('p.level >= :min')
query.expect('p.level <= :max')
query.define('min', 5)
query.define('max', 6)
result = repository.find(query)
And result
becomes:
[
<Player {'level': 5, 'name': 'Sid', 'team': None}>,
<Player {'level': 6, 'name': 'Tsunemori', 'team': None}>
]
In-set query (IN operator)¶
To do in-set search, unlike the previous examples, you can only rely on the parameterization. For example:
query = repository.new_criteria('p')
query.expect('p.level IN :expected_level')
query.define('expected_level', (6, 9)) # or [6, 9]
result = repository.find(query)
And result
becomes:
[
<Player {'level': 9, 'name': 'Ramza', 'team': None}>,
<Player {'level': 6, 'name': 'Tsunemori', 'team': None}>
]
Regular-expression query (LIKE operator)¶
To do in-set search, unlike the previous examples, you can only rely on the parameterization. For example:
query = repository.new_criteria('p')
query.expect('p.name LIKE :name')
query.define('name', '^Ra')
result = repository.find(query)
And result
becomes:
[<Player {'level': 9, 'name': 'Ramza', 'team': None}>]
To just retrieve everything, you can either do:
query = repository.new_criteria()
repository.find(query)
or just go with:
repository.find(query)