-
Notifications
You must be signed in to change notification settings - Fork 60
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
0 parents
commit cc3d215
Showing
73 changed files
with
11,290 additions
and
0 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Sphinx build info version 1 | ||
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done. | ||
config: 2a978427fda753986c5b6cf91a426a93 | ||
tags: 645f666f9bcd5a90fca523b33c5a78b7 |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
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,50 @@ | ||
Advanced Topics | ||
=============== | ||
|
||
Accessing the ``cursor`` object | ||
------------------------------- | ||
|
||
The cursor is a temporary object created in memory that allows you to perform | ||
row-by-row operations on your data and use handy methods such as | ||
``.description``, ``.fetchall()`` and ``.fetchone()``. | ||
As long as you are running a SQL ``SELECT`` query, you can access the cursor | ||
object by appending ``_cursor`` to the end of the queries name. | ||
|
||
For example, say you have the following query named ``get-all-greetings`` in a ``sql`` file: | ||
|
||
.. literalinclude:: ../../example/greetings.sql | ||
:language: sql | ||
:lines: 1-5 | ||
|
||
With this query, you can get all ``greeting_id``'s and ``greeting``'s, access | ||
the cursor object, and print the column names with the following code: | ||
|
||
.. literalinclude:: ../../example/greetings_cursor.py | ||
:language: python | ||
|
||
Accessing prepared SQL as a string | ||
---------------------------------- | ||
|
||
When you need to do something not directly supported by aiosql, this is your | ||
escape hatch. | ||
You can still define your SQL in a file and load it with aiosql, but then you | ||
may choose to use it without calling your aiosql method. | ||
The prepared SQL string of a method is available as an attribute of each method | ||
``queries.<method_name>.sql``. | ||
Here's an example of how you might use it with a unique feature of ``psycopg2`` like | ||
`execute_values <https://www.psycopg.org/docs/extras.html#psycopg2.extras.execute_values>`__. | ||
|
||
.. literalinclude:: ../../example/pg_execute_values.py | ||
:language: python | ||
|
||
Accessing the SQL Operation Type | ||
-------------------------------- | ||
|
||
Query functions also provide access to the SQL operation type you define in | ||
your library. | ||
This can be useful for observability (such as metrics, tracing, or logging), or | ||
customizing how you manage different operations within your codebase. Extending | ||
from the above example: | ||
|
||
.. literalinclude:: ../../example/observe_query.py | ||
:language: python |
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,87 @@ | ||
Contributing | ||
============ | ||
|
||
First, thank you for considering to make a contribution to this project. | ||
Spending your valuable time helping make this project better is deeply appreciated. | ||
All kinds of contributions are helpful and welcome. | ||
|
||
- Report issues `<https://github.com/nackjicholson/aiosql/issues>`__ | ||
- Review or make your own pull requests `<https://github.com/nackjicholson/aiosql/pulls>`__ | ||
- Write documentation `<https://github.com/nackjicholson/aiosql/tree/master/docs>`__ | ||
|
||
Whether you have an idea for a feature improvement or have found a troubling bug, thank you for being here. | ||
|
||
|
||
Packaging & Distribution | ||
------------------------ | ||
|
||
This aiosql repository uses the Python standard packaging tools. | ||
Read about them in more detail at the following links. | ||
|
||
- `Python Packaging User Guide <https://packaging.python.org/>`__ | ||
- `PyPA - Packaging & Distributing projects <https://packaging.python.org/guides/distributing-packages-using-setuptools/>`__ | ||
- `setuptools <https://setuptools.readthedocs.io/en/latest/index.html>`__ | ||
- `build <https://pypa-build.readthedocs.io/en/stable/>`__ | ||
- `twine <https://twine.readthedocs.io/en/latest/#configuration>`__ | ||
|
||
Development Setup | ||
----------------- | ||
|
||
1. Create a virtual environment | ||
|
||
.. code:: sh | ||
# get the project sources | ||
git clone [email protected]:nackjicholson/aiosql.git | ||
cd aiosql | ||
# create a venv manually | ||
python -m venv venv | ||
source venv/bin/activate | ||
pip install --upgrade pip | ||
All subsequent steps will assume you are using python within your activated virtual environment. | ||
|
||
1. Install the development dependencies | ||
|
||
As a development library, aiosql is expected to work with all supported | ||
versions of Python, and many drivers. | ||
The bare minimum of version pinning is declared in the dependencies. | ||
|
||
.. code:: sh | ||
# development tools | ||
pip install .[dev] | ||
# per-database stuff | ||
pip install .[dev-sqlite] | ||
pip install .[dev-postgres] | ||
pip install .[dev-duckdb] | ||
pip install .[dev-mysql] | ||
pip install .[dev-mariadb] | ||
1. Run tests | ||
|
||
.. code:: sh | ||
pytest | ||
Alternatively, there is a convenient ``Makefile`` to automate the above tasks: | ||
|
||
.. code:: sh | ||
make venv.dev # install dev virtual environment | ||
source venv/bin/activate | ||
make check # run all checks: pytest, flake8, coverage… | ||
Also, there is a working ``poetry`` setup in ``pyproject.toml``. | ||
|
||
Dependency Management | ||
--------------------- | ||
|
||
There is no dependency for using ``aiosql`` other than installing your | ||
driver of choice. | ||
|
||
For development you need to test with various databases and even more drivers, | ||
see above for generating a working python environment. | ||
|
||
See also the ``docker`` sub-directory which contains dockerfiles for testing | ||
with Postgres, MySQL and MariaDB. |
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,85 @@ | ||
Database Driver Adapters | ||
======================== | ||
|
||
Database driver adapters in aiosql allow extension of the library to support | ||
additional database drivers. | ||
If you are using a driver other than the ones currently supported by built-in | ||
driver adapters (``sqlite3``, ``apsw``, ``aiosqlite``, ``psycopg``, | ||
``psycopg2``, ``pg8000``, ``pygresql``, ``asyncpg``, ``pymysql``, | ||
``mysqlclient``, ``mysql-connector``, ``duckdb``), first check whether your | ||
driver supports *pyformat* or *named* paramstyles. | ||
If so, check (manually) whether the default PEP 249 drivers work: | ||
|
||
.. code:: python | ||
import acmedb # your PEP 249 driver | ||
import aiosql | ||
conn = acmedb.connect("…") | ||
queries = aiosql.from_str("-- name: add42$\nSELECT :n + 42;\n", acmedb) | ||
assert queries.add42(conn, n=18) == 60 | ||
If this simplistic test works, do more tests involving all operators (see the | ||
pytest tests), then create an issue to notify that your driver works out of the | ||
box so it can be advertised from the readme. | ||
|
||
If it does not work or if you have an asynchronous driver, you will need to make | ||
your own. | ||
Good news, it should be very close to the existing supported drivers. | ||
A database driver adapter is a duck-typed class that follows either of the | ||
``Protocol`` types defined in | ||
`aiosql/types.py <https://github.com/nackjicholson/aiosql/blob/main/aiosql/types.py>`__: | ||
|
||
.. literalinclude:: ../../aiosql/types.py | ||
:language: python | ||
:lines: 61-104 | ||
:caption: PEP 249 Synchronous Adapter | ||
|
||
.. literalinclude:: ../../aiosql/types.py | ||
:language: python | ||
:lines: 107-152 | ||
:caption: Asynchronous Adapter | ||
|
||
Some comments about these classes, one for synchronous queries (PEP 249) and | ||
the other for asynchronous queries: | ||
|
||
- ``_cursor`` is an internal method to generate a cursor, as some drivers | ||
need to pass parameters at this phase. | ||
- ``process_sql`` is used to preprocess SQL queries so has to handle named | ||
parameters as they are managed by the target driver. | ||
- ``select``, ``select_one``, ``insert_update_delete``, ``insert_update_delete_many``, | ||
``insert_returning`` and ``execute_script`` implement all operations. | ||
- ``select_cursor`` returns the raw cursor from a ``select``. | ||
|
||
There isn't much difference between these two protocols besides the | ||
``async def`` syntax for the method definition. | ||
There is one more sneaky difference, the aiosql code expects async adapters to | ||
have a static class field ``is_aio_driver = True`` so it can tell when to use | ||
``await`` for method returns. | ||
Looking at the source of the builtin | ||
`adapters/ <https://github.com/nackjicholson/aiosql/tree/main/aiosql/adapters>`__ | ||
is a great place to start seeing how you may write your own database driver adapter. | ||
|
||
For a PEP 249 driver, consider inheriting from ``aiosql.adapters.Generic`` if you can. | ||
|
||
To use the adapter pass its constructor or factory as the ``driver_adapter`` | ||
argument when building Queries: | ||
|
||
.. code:: python | ||
queries = aiosql.from_path("foo.sql", driver_adapter=AcmeAdapter) | ||
Alternatively, an adapter can be registered or overriden: | ||
|
||
.. code:: python | ||
# in AcmeAdapter provider, eg module "acmedb_aiosql" | ||
import aiosql | ||
aiosql.register_adapter("acmedb", AcmeAdapter) | ||
# then use it elsewhere | ||
import aiosql | ||
queries = aiosql.from_path("some.sql", "acmedb") | ||
Please ask questions on `GitHub Issues <https://github.com/nackjicholson/aiosql/issues>`__. | ||
If the community makes additional adapter add-ons it will be listed from the doc. |
Oops, something went wrong.