summaryrefslogtreecommitdiff
path: root/lib/sqlalchemy/dialects/postgresql/base.py
diff options
context:
space:
mode:
authorMike Bayer <mike_mp@zzzcomputing.com>2022-08-05 13:17:44 -0400
committerMike Bayer <mike_mp@zzzcomputing.com>2022-08-05 13:30:32 -0400
commit8cb6fbfb6589078484f29059dab6bd3e3646f938 (patch)
treede17014518f3cb489e3e9d5cfe9198b8d834d691 /lib/sqlalchemy/dialects/postgresql/base.py
parentbc5b198c6fdc7b8ec04858c35050609404d01291 (diff)
downloadsqlalchemy-8cb6fbfb6589078484f29059dab6bd3e3646f938.tar.gz
credit @zeeeeeb for PG Multirange patch
Also move some of the PG docs to the .rst page so we can link to sections. References: #7156 Change-Id: If57abc768d4768058ffa768f9bf72f83c1ee6c29
Diffstat (limited to 'lib/sqlalchemy/dialects/postgresql/base.py')
-rw-r--r--lib/sqlalchemy/dialects/postgresql/base.py279
1 files changed, 0 insertions, 279 deletions
diff --git a/lib/sqlalchemy/dialects/postgresql/base.py b/lib/sqlalchemy/dialects/postgresql/base.py
index 2ee679e8e..dcd03e625 100644
--- a/lib/sqlalchemy/dialects/postgresql/base.py
+++ b/lib/sqlalchemy/dialects/postgresql/base.py
@@ -1317,285 +1317,6 @@ itself::
.. versionadded:: 1.4.0b2
-ARRAY Types
------------
-
-The PostgreSQL dialect supports arrays, both as multidimensional column types
-as well as array literals:
-
-* :class:`_postgresql.ARRAY` - ARRAY datatype
-
-* :class:`_postgresql.array` - array literal
-
-* :func:`_postgresql.array_agg` - ARRAY_AGG SQL function
-
-* :class:`_postgresql.aggregate_order_by` - helper for PG's ORDER BY aggregate
- function syntax.
-
-JSON Types
-----------
-
-The PostgreSQL dialect supports both JSON and JSONB datatypes, including
-psycopg2's native support and support for all of PostgreSQL's special
-operators:
-
-* :class:`_postgresql.JSON`
-
-* :class:`_postgresql.JSONB`
-
-HSTORE Type
------------
-
-The PostgreSQL HSTORE type as well as hstore literals are supported:
-
-* :class:`_postgresql.HSTORE` - HSTORE datatype
-
-* :class:`_postgresql.hstore` - hstore literal
-
-ENUM Types
-----------
-
-PostgreSQL has an independently creatable TYPE structure which is used
-to implement an enumerated type. This approach introduces significant
-complexity on the SQLAlchemy side in terms of when this type should be
-CREATED and DROPPED. The type object is also an independently reflectable
-entity. The following sections should be consulted:
-
-* :class:`_postgresql.ENUM` - DDL and typing support for ENUM.
-
-* :meth:`.PGInspector.get_enums` - retrieve a listing of current ENUM types
-
-* :meth:`.postgresql.ENUM.create` , :meth:`.postgresql.ENUM.drop` - individual
- CREATE and DROP commands for ENUM.
-
-.. _postgresql_array_of_enum:
-
-Using ENUM with ARRAY
-^^^^^^^^^^^^^^^^^^^^^
-
-The combination of ENUM and ARRAY is not directly supported by backend
-DBAPIs at this time. Prior to SQLAlchemy 1.3.17, a special workaround
-was needed in order to allow this combination to work, described below.
-
-.. versionchanged:: 1.3.17 The combination of ENUM and ARRAY is now directly
- handled by SQLAlchemy's implementation without any workarounds needed.
-
-.. sourcecode:: python
-
- from sqlalchemy import TypeDecorator
- from sqlalchemy.dialects.postgresql import ARRAY
-
- class ArrayOfEnum(TypeDecorator):
- impl = ARRAY
-
- def bind_expression(self, bindvalue):
- return sa.cast(bindvalue, self)
-
- def result_processor(self, dialect, coltype):
- super_rp = super(ArrayOfEnum, self).result_processor(
- dialect, coltype)
-
- def handle_raw_string(value):
- inner = re.match(r"^{(.*)}$", value).group(1)
- return inner.split(",") if inner else []
-
- def process(value):
- if value is None:
- return None
- return super_rp(handle_raw_string(value))
- return process
-
-E.g.::
-
- Table(
- 'mydata', metadata,
- Column('id', Integer, primary_key=True),
- Column('data', ArrayOfEnum(ENUM('a', 'b, 'c', name='myenum')))
-
- )
-
-This type is not included as a built-in type as it would be incompatible
-with a DBAPI that suddenly decides to support ARRAY of ENUM directly in
-a new version.
-
-.. _postgresql_array_of_json:
-
-Using JSON/JSONB with ARRAY
-^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-Similar to using ENUM, prior to SQLAlchemy 1.3.17, for an ARRAY of JSON/JSONB
-we need to render the appropriate CAST. Current psycopg2 drivers accommodate
-the result set correctly without any special steps.
-
-.. versionchanged:: 1.3.17 The combination of JSON/JSONB and ARRAY is now
- directly handled by SQLAlchemy's implementation without any workarounds
- needed.
-
-.. sourcecode:: python
-
- class CastingArray(ARRAY):
- def bind_expression(self, bindvalue):
- return sa.cast(bindvalue, self)
-
-E.g.::
-
- Table(
- 'mydata', metadata,
- Column('id', Integer, primary_key=True),
- Column('data', CastingArray(JSONB))
- )
-
-Range and Multirange Types
---------------------------
-
-PostgreSQL range and multirange types are supported for the psycopg2,
-psycopg, and asyncpg dialects.
-
-Data values being passed to the database may be passed as string
-values or by using the :class:`_postgresql.Range` data object.
-
-.. versionadded:: 2.0 Added the backend-agnostic :class:`_postgresql.Range`
- object used to indicate ranges. The ``psycopg2``-specific range classes
- are no longer exposed and are only used internally by that particular
- dialect.
-
-E.g. an example of a fully typed model using the
-:class:`_postgresql.TSRANGE` datatype::
-
- from datetime import datetime
-
- from sqlalchemy.dialects.postgresql import Range
- from sqlalchemy.dialects.postgresql import TSRANGE
- from sqlalchemy.orm import DeclarativeBase
- from sqlalchemy.orm import Mapped
- from sqlalchemy.orm import mapped_column
-
- class Base(DeclarativeBase):
- pass
-
- class RoomBooking(Base):
-
- __tablename__ = 'room_booking'
-
- id: Mapped[int] = mapped_column(primary_key=True)
- room: Mapped[str]
- during: Mapped[Range[datetime]] = mapped_column(TSRANGE)
-
-To represent data for the ``during`` column above, the :class:`_postgresql.Range`
-type is a simple dataclass that will represent the bounds of the range.
-Below illustrates an INSERT of a row into the above ``room_booking`` table::
-
- from sqlalchemy import create_engine
- from sqlalchemy.orm import Session
-
- engine = create_engine("postgresql+psycopg://scott:tiger@pg14/dbname")
-
- Base.metadata.create_all(engine)
-
- with Session(engine) as session:
- booking = RoomBooking(
- room="101",
- during=Range(datetime(2013, 3, 23), datetime(2013, 3, 25))
- )
- session.add(booking)
- session.commit()
-
-Selecting from any range column will also return :class:`_postgresql.Range`
-objects as indicated::
-
- from sqlalchemy import select
-
- with Session(engine) as session:
- for row in session.execute(select(RoomBooking.during)):
- print(row)
-
-The available range datatypes are as follows:
-
-* :class:`_postgresql.INT4RANGE`
-* :class:`_postgresql.INT8RANGE`
-* :class:`_postgresql.NUMRANGE`
-* :class:`_postgresql.DATERANGE`
-* :class:`_postgresql.TSRANGE`
-* :class:`_postgresql.TSTZRANGE`
-
-.. autoclass:: sqlalchemy.dialects.postgresql.Range
-
-Multiranges
-^^^^^^^^^^^
-
-Multiranges are supported by PostgreSQL 14 and above. SQLAlchemy's
-multirange datatypes deal in lists of :class:`_postgresql.Range` types.
-
-.. versionadded:: 2.0 Added support for MULTIRANGE datatypes. In contrast
- to the ``psycopg`` multirange feature, SQLAlchemy's adaptation represents
- a multirange datatype as a list of :class:`_postgresql.Range` objects.
-
-The example below illustrates use of the :class:`_postgresql.TSMULTIRANGE`
-datatype::
-
- from datetime import datetime
- from typing import List
-
- from sqlalchemy.dialects.postgresql import Range
- from sqlalchemy.dialects.postgresql import TSMULTIRANGE
- from sqlalchemy.orm import DeclarativeBase
- from sqlalchemy.orm import Mapped
- from sqlalchemy.orm import mapped_column
-
- class Base(DeclarativeBase):
- pass
-
- class EventCalendar(Base):
-
- __tablename__ = 'event_calendar'
-
- id: Mapped[int] = mapped_column(primary_key=True)
- event_name: Mapped[str]
- in_session_periods: Mapped[List[Range[datetime]]] = mapped_column(TSMULTIRANGE)
-
-Illustrating insertion and selecting of a record::
-
- from sqlalchemy import create_engine
- from sqlalchemy import select
- from sqlalchemy.orm import Session
-
- engine = create_engine("postgresql+psycopg://scott:tiger@pg14/test")
-
- Base.metadata.create_all(engine)
-
- with Session(engine) as session:
- calendar = EventCalendar(
- event_name="SQLAlchemy Tutorial Sessions",
- in_session_periods= [
- Range(datetime(2013, 3, 23), datetime(2013, 3, 25)),
- Range(datetime(2013, 4, 12), datetime(2013, 4, 15)),
- Range(datetime(2013, 5, 9), datetime(2013, 5, 12)),
- ]
- )
- session.add(calendar)
- session.commit()
-
- for multirange in session.scalars(select(EventCalendar.in_session_periods)):
- for range_ in multirange:
- print(f"Start: {range_.lower} End: {range_.upper}")
-
-.. note:: In the above example, the list of :class:`_postgresql.Range` types
- as handled by the ORM will not automatically detect in-place changes to
- a particular list value; to update list values with the ORM, either re-assign
- a new list to the attribute, or use the :class:`.MutableList`
- type modifier. See the section :ref:`mutable_toplevel` for background.
-
-
-The available multirange datatypes are as follows:
-
-* :class:`_postgresql.INT4MULTIRANGE`
-* :class:`_postgresql.INT8MULTIRANGE`
-* :class:`_postgresql.NUMMULTIRANGE`
-* :class:`_postgresql.DATEMULTIRANGE`
-* :class:`_postgresql.TSMULTIRANGE`
-* :class:`_postgresql.TSTZMULTIRANGE`
-
-
""" # noqa: E501