# Path: psqlextra/type_assertions.py
# def is_query_set(value: Any) -> bool:
#     """Gets whether the specified value is a :see:QuerySet."""
# 
#     return isinstance(value, QuerySet)
# 
# def is_sql(value: Any) -> bool:
#     """Gets whether the specified value could be a raw SQL query."""
# 
#     return isinstance(value, str)
# 
# def is_sql_with_params(value: Any) -> bool:
#     """Gets whether the specified value is a tuple of a SQL query (as a string)
#     and a tuple of bind parameters."""
# 
#     return (
#         isinstance(value, tuple)
#         and len(value) == 2
#         and is_sql(value[0])
#         and isinstance(value[1], Iterable)
#         and not isinstance(value[1], (str, bytes, bytearray))
#     )
# 
# Path: psqlextra/types.py
# SQL = str
#     NOTHING = "NOTHING"
#     UPDATE = "UPDATE"
#     RANGE = "range"
#     LIST = "list"
#     HASH = "hash"
# class StrEnum(str, Enum):
# class ConflictAction(Enum):
# class PostgresPartitioningMethod(StrEnum):
#     def all(cls) -> List["StrEnum"]:
#     def values(cls) -> List[str]:
#     def __str__(self) -> str:
#     def all(cls) -> List["ConflictAction"]:
# 
# Path: psqlextra/models/base.py
# class PostgresModel(models.Model):
#     """Base class for for taking advantage of PostgreSQL specific features."""
# 
#     class Meta:
#         abstract = True
#         base_manager_name = "objects"
# 
#     objects = PostgresManager()
# 
# Path: psqlextra/models/options.py
# class PostgresViewOptions:
#     """Container for :see:PostgresView and :see:PostgresMaterializedView
#     options.
# 
#     This is where attributes copied from the model's `ViewMeta` are
#     held.
#     """
# 
#     def __init__(self, query: Optional[SQLWithParams]):
#         self.query = query
#         self.original_attrs: Dict[str, Optional[SQLWithParams]] = dict(
#             query=self.query
#         )


from typing import Callable, Optional, Union
from django.core.exceptions import ImproperlyConfigured
from django.db import connections
from django.db.models import Model
from django.db.models.base import ModelBase
from django.db.models.query import QuerySet
from psqlextra.type_assertions import is_query_set, is_sql, is_sql_with_params
from psqlextra.types import SQL, SQLWithParams
from .base import PostgresModel
from .options import PostgresViewOptions
        this is because it is what the SQL driver understands and
        we can easily serialize it into a migration.
        """

        # might be a callable to support delayed imports
        view_query = view_query() if callable(view_query) else view_query

        # make sure we don't do a boolean check on query sets,
        # because that might evaluate the query set
        if not is_query_set(view_query) and not view_query:
            return None

        is_valid_view_query = (
            is_query_set(view_query)
            or is_sql_with_params(view_query)
            or is_sql(view_query)
        )

        if not is_valid_view_query:
            raise ImproperlyConfigured(
                (
                    "Model '%s' is not properly configured to be a view."
                    " Set the `query` attribute on the `ViewMeta` class"
                    " to be a valid `django.db.models.query.QuerySet`"
                    " SQL string, or tuple of SQL string and params."
                )
                % (model.__name__)
            )

        # querysets can easily be converted into sql, params

# Path: psqlextra/type_assertions.py
# def is_query_set(value: Any) -> bool:
#     """Gets whether the specified value is a :see:QuerySet."""
# 
#     return isinstance(value, QuerySet)
# 
# def is_sql(value: Any) -> bool:
#     """Gets whether the specified value could be a raw SQL query."""
# 
#     return isinstance(value, str)
# 
# def is_sql_with_params(value: Any) -> bool:
#     """Gets whether the specified value is a tuple of a SQL query (as a string)
#     and a tuple of bind parameters."""
# 
#     return (
#         isinstance(value, tuple)
#         and len(value) == 2
#         and is_sql(value[0])
#         and isinstance(value[1], Iterable)
#         and not isinstance(value[1], (str, bytes, bytearray))
#     )
# 
# Path: psqlextra/types.py
# SQL = str
#     NOTHING = "NOTHING"
#     UPDATE = "UPDATE"
#     RANGE = "range"
#     LIST = "list"
#     HASH = "hash"
# class StrEnum(str, Enum):
# class ConflictAction(Enum):
# class PostgresPartitioningMethod(StrEnum):
#     def all(cls) -> List["StrEnum"]:
#     def values(cls) -> List[str]:
#     def __str__(self) -> str:
#     def all(cls) -> List["ConflictAction"]:
# 
# Path: psqlextra/models/base.py
# class PostgresModel(models.Model):
#     """Base class for for taking advantage of PostgreSQL specific features."""
# 
#     class Meta:
#         abstract = True
#         base_manager_name = "objects"
# 
#     objects = PostgresManager()
# 
# Path: psqlextra/models/options.py
# class PostgresViewOptions:
#     """Container for :see:PostgresView and :see:PostgresMaterializedView
#     options.
# 
#     This is where attributes copied from the model's `ViewMeta` are
#     held.
#     """
# 
#     def __init__(self, query: Optional[SQLWithParams]):
#         self.query = query
#         self.original_attrs: Dict[str, Optional[SQLWithParams]] = dict(
#             query=self.query
#         )


# Path: psqlextra/models/view.py
from typing import Callable, Optional, Union
from django.core.exceptions import ImproperlyConfigured
from django.db import connections
from django.db.models import Model
from django.db.models.base import ModelBase
from django.db.models.query import QuerySet
from psqlextra.type_assertions import is_query_set, is_sql, is_sql_with_params
from psqlextra.types import SQL, SQLWithParams
from .base import PostgresModel
from .options import PostgresViewOptions

        this is because it is what the SQL driver understands and
        we can easily serialize it into a migration.
        """

        # might be a callable to support delayed imports
        view_query = view_query() if callable(view_query) else view_query

        # make sure we don't do a boolean check on query sets,
        # because that might evaluate the query set
        if not is_query_set(view_query) and not view_query:
            return None

        is_valid_view_query = (
            is_query_set(view_query)
            or is_sql_with_params(view_query)
            or is_sql(view_query)
        )

        if not is_valid_view_query:
            raise ImproperlyConfigured(
                (
                    "Model '%s' is not properly configured to be a view."
                    " Set the `query` attribute on the `ViewMeta` class"
                    " to be a valid `django.db.models.query.QuerySet`"
                    " SQL string, or tuple of SQL string and params."
                )
                % (model.__name__)
            )

        # querysets can easily be converted into sql, params

        if is_query_set(view_query):