Select
Selecting data in aiopyql should feel very familiar to SQL syntax
Basic Usage
All Rows & Columns in table"
await db.tables['employees'].select('*')
All Rows & Specific Columns
await db.tables['employees'].select(
'id',
'name',
'position_id'
)
All Rows & Specific Columns with Matching Values
await db.tables['employees'].select(
'id',
'name',
'position_id',
where={
'id': 1000
}
)
All Rows & Specific Columns with Multple Matching Values
await db.tables['employees'].select(
'id',
'name',
'position_id',
where={
'id': 1000,
'name': 'Frank Franklin'
}
)
Advanced
All Rows & Columns from employees, Combining ALL Rows & Columns of table positions (if foreign keys match)
# Basic Join
await db.tables['employees'].select(
'*',
join='positions'
)
SELECT *
FROM
employees
JOIN positions ON
employees.position_id = positions.id
[
{
'employees.id': 1000,
'employees.name': 'Frank Franklin',
'employees.position_id': 100101,
'positions.name': 'Director',
'positions.department_id': 1001
},
...
]
All Rows & Specific Columns from employees, Combining All Rows & Specific Columns of table positions (if foreign keys match)
Basic Join
await db.tables['employees'].select(
'employees.name',
'positions.name',
join='positions' # # possible only if foreign key relation exists between employees & positions
)
SELECT
employees.name,positions.name
FROM employees
JOIN positions ON
employees.position_id = positions.id
[
{'employees.name': 'Frank Franklin', 'positions.name': 'Director'},
{'employees.name': 'Eli Doe', 'positions.name': 'Manager'},
...
]
Basic Join w/ conditions
join='positions'
This syntax is possible if the calling table "await db.tables['employees']" has a foreign-key reference to table 'positions'
await db.tables['employees'].select(
'employees.name',
'positions.name',
join='positions',
where={
'positions.name': 'Director'}
)
SELECT
employees.name,
positions.name
FROM
employees
JOIN positions ON
employees.position_id = positions.id
WHERE
positions.name='Director'
[
{
'employees.name': 'Frank Franklin',
'positions.name': 'Director'
},
{
'employees.name': 'Elly Doe',
'positions.name': 'Director'
},
..
]
Multi-table Join with conditions
await db.tables['employees'].select(
'employees.name',
'positions.name',
'departments.name',
join={
'positions': {
'employees.position_id': 'positions.id'
},
'departments': {
'positions.department_id': 'departments.id'
}
},
where={
'positions.name': 'Director'
}
)
SELECT
employees.name,positions.name,
departments.name
FROM employees
JOIN positions ON
employees.position_id = positions.id
JOIN departments ON
positions.department_id = departments.id
WHERE
positions.name='Director'
[
{
'employees.name': 'Frank Franklin',
'positions.name': 'Director',
'departments.name': 'HR'
},
{
'employees.name': 'Elly Doe',
'positions.name': 'Director',
'departments.name': 'Sales'
}
]
Considerations
When performing multi-table joins, joining columns must be explicity provided.
The key-value order is not explicity important, but will determine which column name is present in returned rows
join={'y_table': {'y_table.id': 'x_table.y_id'}}
[
{'x_table.a': 'val1', 'y_table.id': 'val2'},
{'x_table.a': 'val1', 'y_table.id': 'val3'}
]
join={'y_table': {'x_table.y_id': 'y_table.id'}}
[
{'x_table.a': 'val1', 'x_table.y_id': 'val2'},
{'x_table.a': 'val1', 'x_table.y_id': 'val3'}
]
Operators
The Following operators are supported within the list query syntax
'=', '==', '<>', '!=', '>', '>=', '<', '<=', 'like', 'in', 'not in', 'not like'
Usage
Operator Syntax Requires a list-of-lists and supports multiple combined conditions
await db.tables['table'].select(
'*',
where=[
[condition1],
[condition2],
[condition3]
]
)
await db.tables['table'].select(
'*',
where=[
['col1', 'like', 'abc*'], # Wildcards
['col2', '<', 10], # Value Comparison
['col3', 'not in', ['a', 'b', 'c'] ] # Inclusion / Exclusion
]
)
Examples
Search for rows which contain specified chars using wild card '*'
find_employee = await db.tables['employees'].select(
'id',
'name',
where=[
['name', 'like', '*ank*'] # Double Wild Card - Search
]
)
SELECT id,name FROM employees WHERE name like '%ank%'
[
{'id': 1016, 'name': 'Frank Franklin'},
{'id': 1018, 'name': 'Joe Franklin'},
{'id': 1034, 'name': 'Dana Franklin'},
{'id': 1036, 'name': 'Jane Franklin'},
{'id': 1043, 'name': 'Eli Franklin'},
]
Select Rows using Join and exluding rows with sepcific values
join_sel = db.tables['employees'].select(
'*',
join={
'positions': {
'employees.position_id':'positions.id',
'positions.id': 'employees.position_id'
}
},
where=[
[
'positions.name', 'not in', ['Manager', 'Intern', 'Rep'] # Exclusion within Join
],
[
'positions.department_id', '<>', 2001 # Exclusion via NOT EQUAL
]
]
)
SELECT * FROM employees
JOIN positions ON
employees.position_id = positions.id
AND
positions.id = employees.position_id
WHERE
positions.name not in ('Manager', 'Intern', 'Rep')
AND
positions.department_id <> 2001
Dictionary Lookup
Bracket indexs can only be used for primary keys and return entire row, if existent
await db.tables['employees'][1000]
SELECT * FROM employees WHERE id=1000
{'id': 1000, 'name': 'Frank Franklin', 'position_id': 100101}
db.tables['employees'][1000]
Tip
As this returns an 'awaitable', sub keys cannot be specified until the object has been 'awaited'
# Incorrect
emp_id = await db.tables['employees'][1000]['id']
__main__:1: RuntimeWarning: coroutine was never awaited
RuntimeWarning: Enable tracemalloc to get the object allocation traceback
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'coroutine' object is not subscriptable
# Correct
sel = await db.tables['employees'][1000]
emp_id = sel['id]
Iterate over rows via async for
Requires client side filtering if results must be reduced
async for row in db.tables['employees']:
print(row['id'], row['name'])
SELECT * FROM employees
1000 Frank Franklin
1001 Eli Doe
1002 Chris Smith
1003 Clara Carson
List comprehension
sel = [tuple(row['id'], row['name']) async for row in db.tables['employees']]
SELECT * FROM employees
[
(1000, 'Frank Franklin'),
(1001, 'Eli Doe'),
(1002, 'Chris Smith'),
(1003, 'Clara Carson'),
...
]