aiosql
repository·main·Indexed 23 days ago
https://github.com/nackjicholson/aiosqlA library for asynchronous SQL execution in Python (version 15.0). It allows loading SQL queries from files or strings using from_path() and from_str(), generating dynamic methods via the Queries class. It supports multiple database engines including Postgres, MySQL, MariaDB, and MS SQL Server through built-in and custom driver adapters. The library uses a specific comment syntax (-- name:) to define query names, parameters, and operation types such as SELECT_ONE, SELECT_VALUE, and mutations.
What's inside aiosql
- You can annotate query names with specific operator symbols to control how aiosql executes the query and what data it returns to Python. By default (no operator), aiosql executes the query and returns all results (a relation).
Implement a custom database driver adapter
mainIf your driver is asynchronous or does not work with the default PEP 249 implementation, you must implement a custom adapter. An adapter is a duck-typed class that must follow one of two protocols defined in
aiosql/types.py: the PEP 249 Synchronous Adapter or the Asynchronous Adapter.Key Implementation Details
- Async Adapters: Must include the static class field
is_aio_driver = Truesoaiosqlknows toawaitmethod returns. - Internal Methods:
_cursoris used to generate a cursor (allowing for driver-specific parameters during this phase). - SQL Preprocessing:
process_sqlhandles preprocessing SQL queries and must manage named parameters as required by the target driver. - Core Operations: You must implement
select,select_one,insert_update_delete,insert_update_delete_many,insert_returning, andexecute_script. - Cursor Access:
select_cursorreturns the raw cursor from aselectoperation.
Implementation Tips
- For PEP 249 (synchronous) drivers, consider inheriting from
aiosql.adapters.Generic. - For inspiration, examine the source code in
aiosql/adapters/.
- Async Adapters: Must include the static class field
Understand aiosql dependency management
mainFor standard users,
aiosqlhas no mandatory dependencies other than the specific database driver you choose to use.For developers, additional dependencies are required to test against various databases and drivers. The project also provides Dockerfiles in the
docker/subdirectory for testing against Postgres, MySQL, MariaDB, and MS SQL Server.Use named parameters and avoid positional arguments
mainIn version 13.0 and later, AioSQL introduced stricter parameter handling to improve reliability:
- Named Parameter Declarations: You can add optional parameter declarations directly to your SQL queries.
- Positional Parameter Restriction: When named parameters are declared in a query, AioSQL forbids the use of positional parameters for that query. You must use the named arguments.
kwargs_only: You can use thekwargs_onlyoption to force the library to fail if simple positional arguments are passed instead of keyword arguments.
How aiosql works: Organizing SQL in files
mainaiosqlallows you to write parametric SQL queries in.sqlfiles and load them into your Python application as callable methods. This keeps SQL code separate from Python logic, allowing you to use the same.sqlfiles in other tools likepsqlor GUI clients.To define a method, use the
-- name: method_name(optional_params)comment syntax above your SQL statement.Example
greetings.sql:-- name: get_all_greetings() -- Get all the greetings in the database select greeting_id, greeting from greetings order by 1; -- name: get_user_by_username(username)^ -- Get a user from the database using a named parameter select user_id, username, name from users where username = :username;Note: Adding parameters in parentheses like
(username)is optional but enforces their presence.-- name: get_all_greetings() -- Get all the greetings in the database select greeting_id, greeting from greetings order by 1; -- name: get_user_by_username(username)^ -- Get a user from the database using a named parameter select user_id, username, name from users where username = :username;Install development dependencies for aiosql
mainTo support development and testing across different database drivers, install the
[dev]extra along with specific database extras.Install the base development tools:
pip install .[dev]Then, install the specific extras for the databases you intend to test against:
- SQLite:
.[dev-sqlite] - Postgres:
.[dev-postgres] - DuckDB:
.[dev-duckdb] - MySQL:
.[dev-mysql] - MariaDB:
.[dev-mariadb]
# 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]- SQLite:
Build a custom AioSQL client image
mainYou can build a specific AioSQL client image (e.g., for MySQL) using the
docker buildcommand and the correspondingdockerfile.python-*file.docker build -t aiosql-python-mysql -f dockerfile.python-mysql .Run Docker clients against manually started servers
mainIf you have database servers running manually (not via Docker Compose), you can run AioSQL client containers and point them to your host machine using
--add-host=host.docker.internal:host-gatewayand setting the appropriate host environment variable.Commands for different databases:
- MariaDB/SQLite/DuckDB: Use
python-aiosql-dbswithMA_HOST=host.docker.internal. - MySQL: Use
python-aiosql-mysqlwithMY_HOST=host.docker.internal. - MS SQL Server: Use
python-aiosql-dbswithMS_HOST=host.docker.internal.
# Run against MariaDB docker run -it -v .:/code --add-host=host.docker.internal:host-gateway \ python-aiosql-dbs \ make VENV=/venv MA_HOST=host.docker.internal check.pytest.mariadb.detached # Run against MySQL docker run -it -v .:/code --add-host=host.docker.internal:host-gateway \ python-aiosql-mysql \ make VENV=/venv MY_HOST=host.docker.internal check.pytest.mysql.detached # Run against MS SQL Server docker run -it -v .:/code --add-host=host.docker.internal:host-gateway \ python-aiosql-dbs \ make VENV=/venv MS_HOST=host.docker.internal check.pytest.mssql.detached- MariaDB/SQLite/DuckDB: Use
Run tests and checks in aiosql
mainYou can run the test suite using
pytestdirectly, or use the providedMakefileto automate the process.Using pytest:
pytestUsing Makefile:
- Install the development virtual environment:
make venv.dev - Activate the environment:
source venv/bin/activate - Run all checks (pytest, flake8, coverage, etc.):
make check
pytest # Alternatively using Makefile make venv.dev source venv/bin/activate make check- Install the development virtual environment:
Install aiosql via pip
mainYou can install
aiosqlfrom PyPI usingpip.pip install aiosqlSet up a development environment for aiosql
mainTo develop on
aiosql, you should first clone the repository and create a manual virtual environment to isolate dependencies.Follow these steps:
- Clone the repository.
- Create and activate a Python virtual environment.
- Upgrade
pip.
All subsequent development steps assume you are working within this activated virtual environment.
# get the project sources git clone git@github.com:nackjicholson/aiosql.git cd aiosql # create a venv manually python -m venv venv source venv/bin/activate pip install --upgrade pipSet up MS SQL Server via Docker
mainTo run an MS SQL Server instance for testing, pull the Microsoft SQL Server image and run it with the required environment variables (
ACCEPT_EULA,MSSQL_SA_PASSWORD, andMSSQL_PID).After starting the container, you can access the server using
sqlcmdviadocker exec.docker pull mcr.microsoft.com/mssql/server:2022-latest docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Abc123.." -e "MSSQL_PID=Developer" \ -p 1433:1433 --name mssqltest --hostname mssqltest -d mcr.microsoft.com/mssql/server:2022-latest # Access the server via sqlcmd docker exec -it mssqltest /opt/mssql-tools18/bin/sqlcmd -C -S localhost -U sa -P "Abc123.."