diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ccaaa815..62c5205f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -14,21 +14,34 @@ jobs: matrix: tox-env: # Django 4.2 LTS - Python 3.8, 3.9, 3.10, 3.11, 3.12 - - "py38-dj42" - - "py39-dj42" - - "py310-dj42" - - "py311-dj42" - - "py312-dj42" + - "py38-dj42-psycopg2" + - "py39-dj42-psycopg2" + - "py310-dj42-psycopg2" + - "py311-dj42-psycopg2" + - "py312-dj42-psycopg2" + - "py38-dj42-psycopg" + - "py39-dj42-psycopg" + - "py310-dj42-psycopg" + - "py311-dj42-psycopg" + - "py312-dj42-psycopg" # Django 5.1 - Python 3.10, 3.11, 3.12, 3.13 - - "py310-dj51" - - "py311-dj51" - - "py312-dj51" - - "py313-dj51" + - "py310-dj51-psycopg2" + - "py311-dj51-psycopg2" + - "py312-dj51-psycopg2" + - "py313-dj51-psycopg2" + - "py310-dj51-psycopg" + - "py311-dj51-psycopg" + - "py312-dj51-psycopg" + - "py313-dj51-psycopg" # Django 5.2 LTS - Python 3.10, 3.11, 3.12, 3.13 - - "py310-dj52" - - "py311-dj52" - - "py312-dj52" - - "py313-dj52" + - "py310-dj52-psycopg2" + - "py311-dj52-psycopg2" + - "py312-dj52-psycopg2" + - "py313-dj52-psycopg2" + - "py310-dj52-psycopg" + - "py311-dj52-psycopg" + - "py312-dj52-psycopg" + - "py313-dj52-psycopg" steps: - uses: actions/checkout@v4 diff --git a/README.rst b/README.rst index 3400e74f..0eee83b4 100644 --- a/README.rst +++ b/README.rst @@ -97,6 +97,19 @@ Magic Everyone loves magic! You'll be able to have all this barely having to change your code! +Installation +------------ + +Install django-tenant-schemas with your preferred PostgreSQL client: + +.. code-block:: bash + + # For psycopg2 + pip install django-tenant-schemas[psycopg2] + + # For psycopg + pip install django-tenant-schemas[psycopg] + Setup & Documentation --------------------- diff --git a/docs/install.rst b/docs/install.rst index a0fa4733..95098fd5 100644 --- a/docs/install.rst +++ b/docs/install.rst @@ -2,11 +2,22 @@ Installation ============ -Assuming you have django installed, the first step is to install ``django-tenant-schemas``. +Assuming you have django installed, the first step is to install ``django-tenant-schemas`` with your preferred PostgreSQL client. + +.. code-block:: bash + + # For psycopg2 + pip install django-tenant-schemas[psycopg2] + + # For psycopg + pip install django-tenant-schemas[psycopg] + +You can also install the base package without a PostgreSQL client if you want to manage the dependency separately: .. code-block:: bash pip install django-tenant-schemas + pip install psycopg2-binary # or psycopg[binary]>=3.0 Basic Settings ============== diff --git a/pyproject.toml b/pyproject.toml index 11027aa5..d1cd6e26 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -30,7 +30,6 @@ classifiers = [ dependencies = [ "Django>=4.2", "ordered-set", - "psycopg2-binary", ] dynamic = ["version"] @@ -63,6 +62,10 @@ ignore = ["C901", "E501", "E731", "W503"] [tool.bdist_wheel] universal = false +[project.optional-dependencies] +psycopg2 = ["psycopg2-binary"] +psycopg = ["psycopg[binary]>=3.0"] + [dependency-groups] dev = [ "coverage>=7.6.1", diff --git a/src/tenant_schemas/postgresql_backend/base.py b/src/tenant_schemas/postgresql_backend/base.py index 212d3eae..42c63521 100644 --- a/src/tenant_schemas/postgresql_backend/base.py +++ b/src/tenant_schemas/postgresql_backend/base.py @@ -1,6 +1,5 @@ import re import warnings -import psycopg2 from django.conf import settings from django.contrib.contenttypes.models import ContentType @@ -10,9 +9,16 @@ from tenant_schemas.utils import get_public_schema_name, get_limit_set_calls from tenant_schemas.postgresql_backend.introspection import DatabaseSchemaIntrospection +try: + try: + from psycopg import InternalError + except ImportError: + from psycopg2 import InternalError +except ImportError: + raise ImproperlyConfigured("Error loading psycopg2 or psycopg module") -ORIGINAL_BACKEND = getattr(settings, 'ORIGINAL_BACKEND', 'django.db.backends.postgresql_psycopg2') -# Django 1.9+ takes care to rename the default backend to 'django.db.backends.postgresql' + +ORIGINAL_BACKEND = getattr(settings, 'ORIGINAL_BACKEND', 'django.db.backends.postgresql') original_backend = django.db.utils.load_backend(ORIGINAL_BACKEND) EXTRA_SEARCH_PATHS = getattr(settings, 'PG_EXTRA_SEARCH_PATHS', []) @@ -155,7 +161,7 @@ def _cursor(self, name=None): # we do not have to worry that it's not the good one try: cursor_for_search_path.execute('SET search_path = {0}'.format(','.join(search_paths))) - except (django.db.utils.DatabaseError, psycopg2.InternalError): + except (django.db.utils.DatabaseError, InternalError): self.search_path_set = False else: self.search_path_set = True diff --git a/tox.ini b/tox.ini index 70343b86..7ad5ed4b 100644 --- a/tox.ini +++ b/tox.ini @@ -1,7 +1,7 @@ [tox] envlist = - py{38,39,310,311,312}-dj42-{standard,parallel} - py{310,311,312,313}-dj{51,52}-{standard,parallel} + py{38,39,310,311,312}-dj42-{psycopg2,psycopg}-{standard,parallel} + py{310,311,312,313}-dj{51,52}-{psycopg2,psycopg}-{standard,parallel} skip_missing_interpreters = true requires = tox-docker @@ -19,6 +19,8 @@ commands = dj42: uv pip install "Django>=4.2,<5.0" dj51: uv pip install "Django>=5.1,<5.2" dj52: uv pip install "Django>=5.2,<6.0" + psycopg2: uv pip install "django-tenant-schemas[psycopg2]" + psycopg: uv pip install "django-tenant-schemas[psycopg]" coverage run dts_test_project/manage.py test -v 2 --noinput {posargs:tenant_schemas} coverage report -m --include=src/tenant_schemas/* --omit=src/tenant_schemas/**/test_*.py docker = db