Skip to content

Commit

Permalink
Multiple minor improvements in docs
Browse files Browse the repository at this point in the history
  • Loading branch information
lorinkoz committed Apr 21, 2020
1 parent 057b3a6 commit 36302f4
Show file tree
Hide file tree
Showing 5 changed files with 125 additions and 104 deletions.
2 changes: 1 addition & 1 deletion django_pgschemas/urlresolvers.py
Expand Up @@ -103,7 +103,7 @@ def __getattr__(self, attr):
def get_urlconf_from_schema(schema):
"""
Returns the proper URLConf depending on the schema.
The schema must come with domain_url and folder members set.
The schema must come with ``domain_url`` and ``folder`` members set.
"""
assert isinstance(schema, SchemaDescriptor)

Expand Down
109 changes: 66 additions & 43 deletions docs/advanced.rst
@@ -1,6 +1,63 @@
Advanced configuration
======================

Fast dynamic tenant creation
----------------------------

Every time a instance of ``settings.TENANTS["public"]["TENANT_MODEL"]`` is
created, by default, the corresponding schema is created and synchronized
automatically. Depending on the number of migrations you already have in place,
or the amount of time these could take, or whether you need to pre-populate the
newly created schema with fixtures, this process could take a considerable
amount of time.

If you need a faster creation of dynamic schemas, you can do so by provisioning
a "reference" schema that can cloned into new schemas.

.. code-block:: python
TENANTS = {
# ...
"default": {
# ...
"CLONE_REFERENCE": "sample",
},
}
Once you have this in your settings, you need to prepare your reference schema
with everything a newly created dynamic schema will need. The first step is
actually creating and synchronizing the reference schema. After that, you
can run any command on it, or edit its tables via ``shell``.

.. code-block:: bash
python manage.py createrefschema
python runschema loaddata tenant_app.products -s sample
python runschema shell -s sample
The ``runschema`` command is explained in :ref:`Management commands`.

You don't need any extra step. As soon as a reference schema is configured,
next time you create an instance of the tenant model, it will clone the
reference schema instead of actually creating and synchronizing the schema.

Most importantly, by default, migrations will include the reference schema, so
that it is kept up to date for future tenant creation.

.. attention::

The database function for cloning schemas requires PostgreSQL 10 or higher,
due to a change in the way sequence information is stored.


.. tip::

The reference schema will get apps from
``settings.TENANTS["default"]["APPS"]`` and may look like any other dynamic
tenant, but it is considered a *static* tenant instead, as there is no
corresponding database entry for it. It's a special case of a static
tenant, and it cannot be routed.

Management commands
-------------------

Expand All @@ -10,11 +67,13 @@ the public schema. In order to work around this, we provide a ``runschema``
command that accepts any other command to be run on one or multiple schemas. A
concise synopsis of the ``runschema`` command is as follows::

usage: manage.py runschema [--noinput] [-s SCHEMAS [SCHEMAS ...]]
[-as] [-ss] [-ds] [-ts]
[--executor {sequential,parallel}]
[--no-create-schemas]
command_name
usage: manage.py runschema [-s SCHEMAS [SCHEMAS ...]]
[-x EXCLUDED_SCHEMAS [EXCLUDED_SCHEMAS ...]]
[-as] [-ss] [-ds] [-ts]
[--executor {sequential,parallel}]
[--no-create-schemas]
[--noinput]
command_name

Wrapper around django commands for use with an individual schema

Expand All @@ -27,7 +86,8 @@ concise synopsis of the ``runschema`` command is as follows::
Tells Django to NOT prompt the user for input of any
kind.

-s SCHEMAS [SCHEMAS ...], --schema SCHEMAS [SCHEMAS ...]
-s SCHEMAS [SCHEMAS ...],
--schema SCHEMAS [SCHEMAS ...]
Schema(s) to execute the current command
-as, --include-all-schemas
Include all schemas when executing the current command
Expand Down Expand Up @@ -133,40 +193,3 @@ In order to generate tenant aware cache keys, you can use
"KEY_FUNCTION": "django_pgschemas.cache.make_key",
}
}
Channels (websockets)
---------------------

We provide a tenant aware protocol router for using with ``channels``. You can
use it as follows:

.. code-block:: python
# routing.py
from django_pgschemas.contrib.channels import TenantProtocolRouter
application = TenantProtocolRouter()
# settings.py
ASGI_APPLICATION = "routing.application"
It requires that you also route the websockets requests, at least for the
dynamic tenants. If you don't route websocket requests for static tenants, the
dynamic route will be used:

.. code-block:: python
TENANTS = {
# ...
"default": {
# ...
"URLCONF": "tenant_app.urls",
"WS_URLCONF": "tenant_app.ws_urls",
}
}
You still need to name your channel groups appropriately, taking the
current tenant into account if you want to keep your groups tenant-specific.
You will get the current tenant in ``scope["tenant"]``.
64 changes: 4 additions & 60 deletions docs/basic.rst
Expand Up @@ -3,16 +3,17 @@ Installation

This app requires:

* python (3.6+)
* django (2.0+)
* psycopg2 (2.7+)
* Python (3.6+)
* Django (2.0+)
* Psycopg2 (2.7+)

You can install ``django-pgschemas`` via ``pip``, ``poetry`` or any other
installer.

.. code-block:: bash
pip install django-pgschemas
# or
poetry add django-pgschemas
Basic Configuration
Expand Down Expand Up @@ -185,60 +186,3 @@ available too. Also, at this point, any request to ``blog.mydomain.com`` or
This means that any call to the methods ``filter``, ``get``, ``save``,
``delete`` or any other function involving a database connection will be done
at the correct schema, be it static or dynamic.

Fast dynamic tenant creation
----------------------------

Every time a instance of ``settings.TENANTS["public"]["TENANT_MODEL"]`` is
created, by default, the corresponding schema is created and synchronized
automatically. Depending on the number of migrations you already have in place,
or the amount of time these could take, or whether you need to pre-populate the
newly created schema with fixtures, this process could take a considerable
amount of time.

If you need a faster creation of dynamic schemas, you can do so by provisioning
a "reference" schema that can cloned into new schemas.

.. code-block:: python
TENANTS = {
# ...
"default": {
# ...
"CLONE_REFERENCE": "sample",
},
}
Once you have this in your settings, you need to prepare your reference schema
with everything a newly created dynamic schema will need. The first step is
actually creating and synchronizing the reference schema. After that, you
can run any command on it, or edit its tables via ``shell``.

.. code-block:: bash
python manage.py createrefschema
python runschema loaddata tenant_app.products -s sample
python runschema shell -s sample
The ``runschema`` command is explained in :ref:`Management commands`.

You don't need any extra step. As soon as a reference schema is configured,
next time you create an instance of the tenant model, it will clone the
reference schema instead of actually creating and synchronizing the schema.

Most importantly, by default, migrations will include the reference schema, so
that it is kept up to date for future tenant creation.

.. attention::

The database function for cloning schemas requires PostgreSQL 10 or higher,
due to a change in the way sequence information is stored.


.. tip::

The reference schema will get apps from
``settings.TENANTS["default"]["APPS"]`` and may look like any other dynamic
tenant, but it is considered a *static* tenant instead, as there is no
corresponding database entry for it. It's a special case of a static
tenant, and it cannot be routed.
53 changes: 53 additions & 0 deletions docs/contrib.rst
@@ -0,0 +1,53 @@
Contributions
=============

All contributions and third party integrations live inside
``django_pgschemas.contrib``.

If you want to implement an integration with other Django packages, please
submit a pull request containing:

* The code for your integration
* The tests for your integration
* The docs for your integration in this section of the documentation

We're striving to maintain/increase our code coverage, but please, make sure your
integration is properly tested. Proper tests will always beat meaningless 100%
coverage.

Channels (websockets)
---------------------

We provide a tenant aware protocol router for using with ``channels``. You can
use it as follows:

.. code-block:: python
# routing.py
from django_pgschemas.contrib.channels import TenantProtocolRouter
application = TenantProtocolRouter()
# settings.py
ASGI_APPLICATION = "routing.application"
It requires that you also route the websockets requests, at least for the
dynamic tenants. If you don't route websocket requests for static tenants, the
dynamic route will be used:

.. code-block:: python
TENANTS = {
# ...
"default": {
# ...
"URLCONF": "tenant_app.urls",
"WS_URLCONF": "tenant_app.ws_urls",
}
}
You still need to name your channel groups appropriately, taking the
current tenant into account if you want to keep your groups tenant-specific.
You will get the current tenant in ``scope["tenant"]``.
1 change: 1 addition & 0 deletions docs/index.rst
Expand Up @@ -45,6 +45,7 @@ django-pgschemas
overview
basic
advanced
contrib
troubleshooting
reference
credits
Expand Down

0 comments on commit 36302f4

Please sign in to comment.