mcfunley / pugsql

A HugSQL-inspired database library for Python
https://pugsql.org
Apache License 2.0
673 stars 22 forks source link

Support multiple query modules #29

Closed filias closed 3 years ago

filias commented 4 years ago

When using pugsql in a separate python package would be useful to define multiple query modules so that users of that package can extend its functionality with new queries.

At the moment we define where our sql queries live like this: queries = pugsql.module("resources/sql")

My proposal is to be able to add other modules where queries can live: queries = pugsql.module("resources/sql") queries.add_module("other_resources/sql")

The add_module would do the work of concatenating all the resources in the existing modules. The main functionality for running queries would be exactly the same.

o-fedorov commented 4 years ago

Here is an example how I resolve this issue for python 3.7+:

from pathlib import Path

import pugsql
from sqlalchemy import create_engine

# Directory that contains SQL "modules" (subdirectories with "*.sql" files)
# There could be directories `resources/sql/module1/`, 
# `resources/sql/module2/` and so on. 
QUERIES_DIR = Path(__file__).parent.parent / "resources" / "sql"

_MODULES = {}

for _module_path in QUERIES_DIR.iterdir():
    _MODULES[module_path.name] = pugsql.module(_module_path)

def __getattr__(name):
    """Dynamically resolve PugSQL modules.

    See https://www.python.org/dev/peps/pep-0562/ for details.
    """
    try:
        return _MODULES[name]
    except KeyError:
        raise AttributeError(name)

def connect(connstr, **kwargs):
    """Configure DB connection for all modules."""
    engine = create_engine(connstr, **kwargs)

    for module in _MODULES.values():
        module.set_engine(engine)
mcfunley commented 3 years ago

Added the add_queries method to Module objects in version 0.2.1