-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
2d87259
commit df548f1
Showing
31 changed files
with
2,121 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Empty file.
This file was deleted.
Oops, something went wrong.
Empty file.
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
|
||
Query Builder | ||
+++++++++++++ | ||
|
||
``Dataloom`` exposes a method called ``getQueryBuilder``, which allows you to obtain a ``qb`` object. This object enables you to execute SQL queries directly from SQL scripts. | ||
|
||
.. code-block:: | ||
qb = loom.getQueryBuilder() | ||
print(qb) # ? = Loom QB<mysql> | ||
The ``qb`` object contains the method called ``run``, which is used to execute SQL scripts or SQL queries. | ||
|
||
.. code-block:: | ||
ids = qb.run("select id from posts;", fetchall=True) | ||
print(ids) # ? = [(1,), (2,), (3,), (4,)] | ||
You can also execute SQL files. In the following example, we will demonstrate how you can execute SQL scripts using the ``qb``. Let's say we have an SQL file called ``qb.sql`` which contains the following SQL code: | ||
|
||
.. code-block:: SQL | ||
-- qb.sql | ||
SELECT id, title FROM posts WHERE id IN (1, 3, 2, 4) LIMIT 4 OFFSET 1; | ||
SELECT COUNT(*) FROM ( | ||
SELECT DISTINCT `id` | ||
FROM `posts` | ||
WHERE `id` < 5 | ||
LIMIT 3 OFFSET 2 | ||
) AS subquery; | ||
We can use the query builder to execute the SQL as follows: | ||
|
||
.. code-block:: | ||
with open("qb.sql", "r") as reader: | ||
sql = reader.read() | ||
res = qb.run( | ||
sql, | ||
fetchall=True, | ||
is_script=True, | ||
) | ||
print(res) | ||
.. tip:: 👍 **Pro Tip:** Executing a script using query builder does not return a result. The result value is always ``None``. | ||
|
||
The ``run`` method takes the following as arguments: | ||
|
||
.. rst-class:: my-table | ||
|
||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| Argument | Description | Type | Required | Default | | ||
+===================+==========================================================================================+==================================================================+==========+===========+ | ||
| ``sql`` | SQL query to execute. | ``str`` | `Yes` | | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``args`` | Parameters for the SQL query. | ``Any`` or ``None`` | ``No`` | ``None`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``fetchone`` | Whether to fetch only one result. | ``bool`` | ``No`` | ``False`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``fetchmany`` | Whether to fetch multiple results. | ``bool`` | ``No`` | ``False`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``fetchall`` | Whether to fetch all results. | ``bool`` | ``No`` | ``False`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``mutation`` | Whether the query is a mutation (insert, update, delete). | ``bool`` | ``No`` | ``True`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``bulk`` | Whether the query is a bulk operation. | ``bool`` | ``No`` | ``False`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``affected_rows`` | Whether to return affected rows. | ``bool`` | ``No`` | ``False`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``operation`` | Type of operation being performed. | ``'insert'``, ``'update'``, ``'delete'``, ``'read'`` or ``None`` | ``No`` | ``False`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``verbose`` | Verbosity level for logging . Set this option to ``0`` if you don't want logging at all. | ``int`` | ``No`` | ``1`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
| ``is_script`` | Whether the SQL is a script. | ``bool`` | ``No`` | ``False`` | | ||
+-------------------+------------------------------------------------------------------------------------------+------------------------------------------------------------------+----------+-----------+ | ||
|
||
|
||
Why Use Query Builder? | ||
---------------------- | ||
|
||
- The query builder empowers developers to seamlessly execute ``SQL`` queries directly. | ||
- While Dataloom primarily utilizes ``subqueries`` for eager data fetching on models, developers may prefer to employ JOIN operations, which are achievable through the ``qb`` object. | ||
|
||
.. code-block:: | ||
qb = loom.getQueryBuilder() | ||
result = qb.run("SELECT * FROM table1 INNER JOIN table2 ON table1.id = table2.table1_id;") | ||
print(result) | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
4. What about ``bidirectional`` queries? | ||
++++++++++++++++++++++++++++++++++++++++ | ||
|
||
In ``Dataloom``, we support bidirectional relations with eager loading on-the-fly. You can query from a ``parent`` to a ``child`` and from a ``child`` to a ``parent``. You just need to know how the relationship is mapped between these two models. In this case, the `has` option is very important in the `Include` class. Here are some examples demonstrating bidirectional querying between `user` and `post`, where the `user` is the parent table and the `post` is the child table in this case. | ||
|
||
1. Child to Parent | ||
================== | ||
|
||
Here is an example illustrating how we can query a parent from child table. | ||
|
||
.. code-block:: | ||
posts_users = mysql_loom.find_many( | ||
Post, | ||
limit=2, | ||
offset=3, | ||
order=[Order(column="id", order="DESC")], | ||
select=["id", "title"], | ||
include=[ | ||
Include( | ||
model=User, | ||
select=["id", "username"], | ||
has="one", | ||
include=[Include(model=Profile, select=["id", "avatar"], has="one")], | ||
), | ||
Include( | ||
model=Category, | ||
select=["id", "type"], | ||
order=[Order(column="id", order="DESC")], | ||
has="many", | ||
limit=2, | ||
), | ||
], | ||
) | ||
print(posts_users) # ? = [{'id': 1, 'title': 'Hey', 'user': {'id': 1, 'username': '@miller', 'profile': {'id': 1, 'avatar': 'hello.jpg'}}, 'categories': [{'id': 4, 'type': 'sport'}, {'id': 3, 'type': 'tech'}]}] | ||
2. Parent to Child | ||
================== | ||
|
||
Here is an example of how we can query a child table from parent table | ||
|
||
.. code-block:: | ||
user_post = mysql_loom.find_by_pk( | ||
User, | ||
pk=userId, | ||
select=["id", "username"], | ||
include=[ | ||
Include( | ||
model=Post, | ||
limit=2, | ||
offset=3, | ||
order=[Order(column="id", order="DESC")], | ||
select=["id", "title"], | ||
include=[ | ||
Include( | ||
model=User, | ||
select=["id", "username"], | ||
has="one", | ||
include=[ | ||
Include(model=Profile, select=["id", "avatar"], has="one") | ||
], | ||
), | ||
Include( | ||
model=Category, | ||
select=["id", "type"], | ||
order=[Order(column="id", order="DESC")], | ||
has="many", | ||
limit=2, | ||
), | ||
], | ||
), | ||
Include(model=Profile, select=["id", "avatar"], has="one"), | ||
], | ||
) | ||
print(user_post) """ ? = | ||
{'id': 1, 'username': '@miller', 'user': {'id': 1, 'username': '@miller', 'profile': {'id': 1, 'avatar': 'hello.jpg'}}, 'categories': [{'id': 4, 'type': 'sport'}, {'id': 3, 'type': 'tech'}], 'posts': [{'id': 1, 'title': 'Hey', 'user': {'id': 1, 'username': '@miller', 'profile': {'id': 1, 'avatar': 'hello.jpg'}}, 'categories': [{'id': 4, 'type': 'sport'}, {'id': 3, 'type': 'tech'}]}], 'profile': {'id': 1, 'avatar': 'hello.jpg'}} | ||
""" | ||
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
Associations | ||
++++++++++++ | ||
|
||
In dataloom you can create association using the ``foreign-keys`` column during model creation. You just have to specify a single model to have a relationship with another model using the ``ForeignKeyColum``. Just by doing that ``dataloom`` will be able to learn bidirectional relationship between your models. Let's have a look at the following examples: | ||
|
||
#. `One to One Association <one_to_one.html>`_ | ||
#. `One to Many Association <one_to_n.html>`_ | ||
#. `Many to One Association <n_to_one.html>`_ | ||
#. `What about bidirectional queries? <bi_directional.html>`_ | ||
#. `Self Association <self_relations.html>`_ | ||
#. `Many to Many Association <n_to_n.html>`_ | ||
|
||
|
||
|
||
.. toctree:: | ||
:maxdepth: 2 | ||
:hidden: | ||
|
||
one_to_one | ||
one_to_n | ||
n_to_one | ||
bi_directional | ||
self_relations | ||
n_to_n | ||
|
Oops, something went wrong.