# -*- coding: utf-8 -*-
from distutils.core import setup

packages = \
['django_pgschemas',
 'django_pgschemas.channels',
 'django_pgschemas.management',
 'django_pgschemas.management.commands',
 'django_pgschemas.postgresql_backend',
 'django_pgschemas.test']

package_data = \
{'': ['*']}

install_requires = \
['django>=2.0,<3.0', 'psycopg2-binary>=2.7,<3.0']

setup_kwargs = {
    'name': 'django-pgschemas',
    'version': '0.1.2',
    'description': 'Multi-tenancy on Django using PostgreSQL schemas.',
    'long_description': 'django-pgschemas\n================\n\n.. image:: https://img.shields.io/badge/packaging-poetry-purple.svg\n   :alt: Packaging: poetry\n   :target: https://github.com/sdispater/poetry\n\n.. image:: https://img.shields.io/badge/code%20style-black-black.svg\n   :alt: Code style: black\n   :target: https://github.com/ambv/black\n\n.. image:: https://badges.gitter.im/Join%20Chat.svg\n   :alt: Join the chat at https://gitter.im/django-pgschemas\n   :target: https://gitter.im/django-pgschemas/community?utm_source=share-link&utm_medium=link&utm_campaign=share-link\n\n.. image:: https://readthedocs.org/projects/django-pgschemas/badge/?version=latest\n    :alt: Documentation status\n    :target: https://django-pgschemas.readthedocs.io/\n\nSchemas\n-------\n\nThis app uses PostgreSQL schemas to support data multi-tenancy in a single\nDjango project. For an accurate description on schemas, see `the official\ndocumentation on PostgreSQL schemas`_.\n\n.. _the official documentation on PostgreSQL schemas: http://www.postgresql.org/docs/9.1/static/ddl-schemas.html\n\nThe terms *schema* and *tenant* are used indistinctly all over the\ndocumentation. However, it is important to note some subtle differences between\nthe two. We consider a *tenant* to be a subset of data that can be accessed\nwith a URL (routed), and we use database *schemas* for that purpose. Still,\nthere can be schemas that shouldn\'t be considered tenants according to our\ndefinition. One good example is the ``public`` schema, which contains data\nshared across all tenants. That said, remember that every tenant is a schema,\nbut not every schema is a tenant.\n\nUsage\n-----\n\nUse ``django_pgschemas.postgresql_backend`` as your database engine.\n\n.. code-block:: python\n\n    DATABASES = {\n        "default": {\n            "ENGINE": "django_pgschemas.postgresql_backend",\n            # ...\n        }\n    }\n\nAdd the middleware ``django_pgschemas.middleware.TenantMiddleware`` to the top\nof ``MIDDLEWARE``, so that each request can be set to use the correct schema.\n\n.. code-block:: python\n\n    MIDDLEWARE = (\n        "django_pgschemas.middleware.TenantMainMiddleware",\n        #...\n    )\n\nAdd ``django_pgschemas.routers.SyncRouter`` to your ``DATABASE_ROUTERS``, so\nthat the correct apps can be synced, depending on the target schema.\n\n.. code-block:: python\n\n    DATABASE_ROUTERS = (\n        "django_pgschemas.routers.SyncRouter",\n        #...\n    )\n\nAdd the minimal tenant configuration.\n\n.. code-block:: python\n\n    TENANTS = {\n        "public": {\n            "APPS": [\n                "django.contrib.contenttypes",\n                "django.contrib.staticfiles",\n                # ...\n                "django_pgschemas",\n                "shared_app",\n                # ...\n            ],\n            "TENANT_MODEL": "shared_app.Client",\n            "DOMAIN_MODEL": "shared_app.Domain",\n        },\n        # ...\n        "default": {\n            "APPS": [\n                "django.contrib.auth",\n                "django.contrib.sessions",\n                # ...\n                "tenant_app",\n                # ...\n            ],\n            "URLCONF": "tenant_app.urls",\n        }\n    }\n\nEach entry in the ``TENANTS`` dictionary represents a static tenant, except for\n``default``, which controls the settings for dynamic tenants (that is, database\ncontrolled). ``public`` is always treated as shared schema and cannot be routed\ndirectly.\n\nMore static tenants can be added and routed.\n\n.. code-block:: python\n\n    TENANTS = {\n        # ...\n        "www": {\n            "APPS": [\n                "django.contrib.auth",\n                "django.contrib.sessions",\n                # ...\n                "main_app",\n            ],\n            "DOMAINS": ["mydomain.com"],\n            "URLCONF": "main_app.urls",\n        },\n        "blog": {\n            "APPS": [\n                "django.contrib.auth",\n                "django.contrib.sessions",\n                # ...\n                "blog_app",\n            ],\n            "DOMAINS": ["blog.mydomain.com", "help.mydomain.com"],\n            "URLCONF": "blog_app.urls",\n        },\n        # ...\n    }\n\nFor Django to function properly, ``INSTALLED_APPS`` and ``ROOT_URLCONF``\nsettings must be defined. Just make them get their information from the\n``TENANTS`` dictionary, for the sake of consistency.\n\n.. code-block:: python\n\n    INSTALLED_APPS = []\n    for schema in TENANTS:\n        INSTALLED_APPS += [app for app in TENANTS[schema]["APPS"] if app not in INSTALLED_APPS]\n\n    ROOT_URLCONF = TENANTS["default"]["URLCONF"]\n\nDynamic tenants need to be created through instances of\n``TENANTS["public"]["TENANT_MODEL"]``.\n\n.. code-block:: python\n\n    # shared_app/models.py\n\n    from django.db import models\n    from django_pgschemas.models import TenantMixin, DomainMixin\n\n    class Client(TenantMixin):\n        name = models.CharField(max_length=100)\n        paid_until =  models.DateField(blank=True, null=True)\n        on_trial = models.BooleanField(default=True)\n        created_on = models.DateField(auto_now_add=True)\n\n    class Domain(DomainMixin):\n        pass\n\nSync the public schema, in order to get ``Client`` model created. Also sync\nstatic schemas either one by one or using the ``:static:`` wildcard.\n\n.. code-block:: bash\n\n    python manage.py migrateschema -s public\n    python manage.py migrateschema -s :static:\n\nCreate the first dynamic tenant.\n\n>>> from shared_app.models import Client, Domain\n>>> client1 = Client.objects.create(schema_name="client1")\n>>> Domain.objects.create(domain="client1.mydomain.com", tenant=client1, is_primary=True)\n\nNow any request made to ``client1.mydomain.com`` will automatically set\nPostgreSQL\'s ``search_path`` to ``client1`` and ``public``, making shared apps\navailable too. Also, any request to blog.mydomain.com or\nhelp.mydomain.com will set ``search_path`` to ``blog`` and ``public``. This\nmeans that any call to the methods ``filter``, ``get``, ``save``, ``delete``\nor any other function involving a database connection will now be done at the\ncorrect schema, be it static or dynamic.\n\nManagement commands\n-------------------\n\nManagement commands provided by Django or any 3rd party app will run by default\non the ``public`` schema. To run a command on a specific tenant, you can use\nthe provided command ``runschema``.\n\n.. code-block:: bash\n\n    python manage.py runschema shell -s tenant1\n    python manage.py runschema loaddata tenant_app.Products -s :dynamic:\n\nWe provide a custom ``migrateschema`` command (also aliased as ``migrate``)\nthat is capable of running migrations on specific schemas.\n\n.. code-block:: bash\n\n    # all schemas\n    python manage.py migrate\n\n    # static schemas only\n    python manage.py migrate -s :static:\n\n    # dynamic schemas only\n    python manage.py migrate -s :dynamic:\n\n    # specific schema by exact schema name\n    python manage.py migrate -s tenant1\n\n    # specific schema by partially matched domain (startswith)\n    python manage.py migrate -s help.mydomain\n\nGotchas\n-------\n\n* It is enforced that ``django.contrib.contenttypes`` should live in the\n  ``public`` schema. This is to guarantee that content types from all\n  apps/tenants are stored in a single place.\n\n* It is enforced that ``django.contrib.sessions`` can only live in schemas\n  where the app that defines the user model also lives. The user app is\n  ``django.contrib.auth`` by default, but could be changed via\n  ``AUTH_USER_MODEL`` setting. This is to guarantee that session information\n  is not leaked across tenants that do not share the same user base.\n\nCredits\n-------\n\nThis project stands on the shoulders of giants.\n\n* Tom Turner with ``django-tenants``.\n* Bernardo Pires with ``django-tenant-schemas``.\n* Vlada Macek with ``django-schemata``.\n',
    'author': 'Lorenzo Peña',
    'author_email': 'lorinkoz@gmail.com',
    'url': 'https://github.com/lorinkoz/django-pgschemas',
    'packages': packages,
    'package_data': package_data,
    'install_requires': install_requires,
    'python_requires': '>=3.5,<4.0',
}


setup(**setup_kwargs)
