PostgreSQL

Unterstützung für die PostgreSQL-Datenbank.

Die folgende Tabelle fasst die aktuellen Support-Level für Datenbank-Release-Versionen zusammen.

Unterstützte PostgreSQL-Versionen

Support-Typ

Versionen

Supported version

9.6+

Best effort

9+

DBAPI-Unterstützung

Die folgenden Dialekt-/DBAPI-Optionen sind verfügbar. Bitte beachten Sie die einzelnen DBAPI-Abschnitte für Verbindungsinformationen.

Sequenzen/SERIAL/IDENTITY

PostgreSQL unterstützt Sequenzen, und SQLAlchemy verwendet diese als Standardmittel zur Erstellung neuer Primärschlüsselwerte für integerbasierte Primärschlüsselspalten. Beim Erstellen von Tabellen gibt SQLAlchemy den SERIAL-Datentyp für integerbasierte Primärschlüsselspalten aus, der eine Sequenz und einen serverseitigen Standardwert für die Spalte generiert.

Um eine bestimmte benannte Sequenz für die Primärschlüsselgenerierung anzugeben, verwenden Sie das Konstrukt Sequence()

Table(
    "sometable",
    metadata,
    Column(
        "id", Integer, Sequence("some_id_seq", start=1), primary_key=True
    ),
)

Wenn SQLAlchemy eine einzelne INSERT-Anweisung ausgibt, um die Bedingung zu erfüllen, dass der "Zuletzt eingefügte Bezeichner" verfügbar ist, wird der Klausel RETURNING eine INSERT-Anweisung hinzugefügt, die angibt, dass die Primärschlüsselspalten nach Abschluss der Anweisung zurückgegeben werden sollen. Die RETURNING-Funktionalität erfolgt nur, wenn PostgreSQL 8.2 oder neuer verwendet wird. Als Fallback-Ansatz wird die Sequenz, ob explizit angegeben oder implizit über SERIAL, unabhängig davon vorher ausgeführt, der zurückgegebene Wert wird in der nachfolgenden Einfügung verwendet. Beachten Sie, dass bei der Ausführung eines insert()-Konstrukts mit "executemany"-Semantik die Funktionalität "Zuletzt eingefügter Bezeichner" nicht angewendet wird; keine RETURNING-Klausel wird ausgegeben, noch wird die Sequenz in diesem Fall vorab ausgeführt.

IDENTITY-Spalten in PostgreSQL 10 und neuer

PostgreSQL 10 und neuer verfügen über eine neue IDENTITY-Funktion, die die Verwendung von SERIAL ersetzt. Das Konstrukt Identity in einer Column kann zur Steuerung ihres Verhaltens verwendet werden

from sqlalchemy import Table, Column, MetaData, Integer, Computed

metadata = MetaData()

data = Table(
    "data",
    metadata,
    Column(
        "id", Integer, Identity(start=42, cycle=True), primary_key=True
    ),
    Column("data", String),
)

Die CREATE TABLE für das obige Table-Objekt wäre

CREATE TABLE data (
    id INTEGER GENERATED BY DEFAULT AS IDENTITY (START WITH 42 CYCLE),
    data VARCHAR,
    PRIMARY KEY (id)
)

Geändert in Version 1.4: Hinzugefügt wurde das Konstrukt Identity in einer Column, um die Option einer automatisch inkrementierenden Spalte anzugeben.

Hinweis

Frühere Versionen von SQLAlchemy hatten keine integrierte Unterstützung für das Rendern von IDENTITY und konnten den folgenden Kompilierungshook verwenden, um Vorkommen von SERIAL durch IDENTITY zu ersetzen

from sqlalchemy.schema import CreateColumn
from sqlalchemy.ext.compiler import compiles


@compiles(CreateColumn, "postgresql")
def use_identity(element, compiler, **kw):
    text = compiler.visit_create_column(element, **kw)
    text = text.replace("SERIAL", "INT GENERATED BY DEFAULT AS IDENTITY")
    return text

Unter Verwendung des Obigen wird eine Tabelle wie

t = Table(
    "t", m, Column("id", Integer, primary_key=True), Column("data", String)
)

Wird in der zugrunde liegenden Datenbank generiert als

CREATE TABLE t (
    id INT GENERATED BY DEFAULT AS IDENTITY,
    data VARCHAR,
    PRIMARY KEY (id)
)

Serverseitige Cursor

Die Unterstützung für serverseitige Cursor ist für die Dialekte psycopg2 und asyncpg verfügbar und kann auch in anderen verfügbar sein.

Serverseitige Cursor werden pro Anweisung aktiviert, indem die Verbindungs-Ausführungsoption Connection.execution_options.stream_results verwendet wird

with engine.connect() as conn:
    result = conn.execution_options(stream_results=True).execute(
        text("select * from table")
    )

Beachten Sie, dass einige Arten von SQL-Anweisungen möglicherweise nicht mit serverseitigen Cursorn unterstützt werden. Im Allgemeinen sollten nur SQL-Anweisungen, die Zeilen zurückgeben, mit dieser Option verwendet werden.

Veraltet seit Version 1.4: Das Dialekt-Flag `server_side_cursors` ist veraltet und wird in einer zukünftigen Version entfernt. Bitte verwenden Sie die Ausführungsoption Connection.stream_results für unbuffered Cursor-Unterstützung.

Transaktionsisolationslevel

Die meisten SQLAlchemy-Dialekte unterstützen die Einstellung der Transaktionsisolationsstufe über den Parameter create_engine.isolation_level auf der Ebene von create_engine() und auf der Ebene von Connection über den Parameter Connection.execution_options.isolation_level.

Für PostgreSQL-Dialekte funktioniert dieses Feature entweder durch Nutzung der DBAPI-spezifischen Funktionen, wie z. B. der Isolationsstufen-Flags von psycopg2, die die Isolationsstufen-Einstellung inline mit der "BEGIN"-Anweisung einbetten, oder für DBAPIs ohne direkte Unterstützung durch die Ausgabe von SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL <level> vor der von der DBAPI ausgegebenen "BEGIN"-Anweisung. Für das spezielle AUTOCOMMIT-Isolationslevel werden DBAPI-spezifische Techniken verwendet, was typischerweise ein .autocommit-Flag auf dem DBAPI-Verbindungsobjekt ist.

Isolationslevel mit create_engine() einstellen

engine = create_engine(
    "postgresql+pg8000://scott:tiger@localhost/test",
    isolation_level="REPEATABLE READ",
)

Einstellung über per-Verbindungs-Ausführungsoptionen

with engine.connect() as conn:
    conn = conn.execution_options(isolation_level="REPEATABLE READ")
    with conn.begin():
        ...  # work with transaction

Es gibt auch weitere Optionen für Isolationslevel-Konfigurationen, wie z. B. „Sub-Engine“-Objekte, die mit einer Haupt- Engine verknüpft sind und jeweils unterschiedliche Isolationslevel-Einstellungen anwenden. Siehe die Diskussion unter Einstellung von Transaktionsisolationsleveln einschließlich DBAPI-Autocommit für Hintergrundinformationen.

Gültige Werte für isolation_level bei den meisten PostgreSQL-Dialekten sind

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • AUTOCOMMIT

Einstellung von READ ONLY / DEFERRABLE

Die meisten PostgreSQL-Dialekte unterstützen die Einstellung der Attribute "READ ONLY" und "DEFERRABLE" der Transaktion, was zusätzlich zur Einstellung der Isolationsstufe erfolgt. Diese beiden Attribute können entweder in Verbindung mit oder unabhängig von der Isolationsstufe festgelegt werden, indem die Flags postgresql_readonly und postgresql_deferrable mit Connection.execution_options() übergeben werden. Das folgende Beispiel zeigt die Übergabe der Isolationsstufe "SERIALIZABLE" zusammen mit der Einstellung von "READ ONLY" und "DEFERRABLE"

with engine.connect() as conn:
    conn = conn.execution_options(
        isolation_level="SERIALIZABLE",
        postgresql_readonly=True,
        postgresql_deferrable=True,
    )
    with conn.begin():
        ...  # work with transaction

Beachten Sie, dass einige DBAPIs wie asyncpg "readonly" nur mit SERIALIZABLE-Isolation unterstützen.

Neu in Version 1.4: Unterstützung für die Ausführungsoptionen postgresql_readonly und postgresql_deferrable hinzugefügt.

Temporäre Tabellen / Ressourcenrücksetzung für Connection Pooling

Die QueuePool-Connection-Pool-Implementierung, die von dem Engine-Objekt von SQLAlchemy verwendet wird, enthält ein Rücksetzungsverhalten bei Rückgabe, das die .rollback()-Methode der DBAPI aufruft, wenn Verbindungen an den Pool zurückgegeben werden. Während dieses Rollback den unmittelbaren Zustand der vorherigen Transaktion löscht, deckt es keine größere Bandbreite an Sitzungszuständen ab, einschließlich temporärer Tabellen sowie anderer Serverzustände wie vorbereitete Anweisungshandles und Anweisungs-Caches. Die PostgreSQL-Datenbank enthält eine Vielzahl von Befehlen, die zur Rücksetzung dieses Zustands verwendet werden können, darunter DISCARD, RESET, DEALLOCATE und UNLISTEN.

Um einen oder mehrere dieser Befehle als Mittel zur Durchführung der Rücksetzung bei Rückgabe zu installieren, kann der Event-Hook PoolEvents.reset() verwendet werden, wie im folgenden Beispiel gezeigt. Die Implementierung beendet laufende Transaktionen sowie verwirft temporäre Tabellen unter Verwendung der Befehle CLOSE, RESET und DISCARD; siehe die PostgreSQL-Dokumentation für Hintergrundinformationen darüber, was jeder dieser Befehle tut.

Der Parameter create_engine.pool_reset_on_return ist auf None gesetzt, damit das benutzerdefinierte Schema das Standardverhalten vollständig ersetzen kann. Die benutzerdefinierte Hook-Implementierung ruft in jedem Fall .rollback() auf, da es normalerweise wichtig ist, dass die eigene Verfolgung von Commit/Rollback der DBAPI mit dem Transaktionszustand übereinstimmt.

from sqlalchemy import create_engine
from sqlalchemy import event

postgresql_engine = create_engine(
    "postgresql+pyscopg2://scott:tiger@hostname/dbname",
    # disable default reset-on-return scheme
    pool_reset_on_return=None,
)


@event.listens_for(postgresql_engine, "reset")
def _reset_postgresql(dbapi_connection, connection_record, reset_state):
    if not reset_state.terminate_only:
        dbapi_connection.execute("CLOSE ALL")
        dbapi_connection.execute("RESET ALL")
        dbapi_connection.execute("DISCARD TEMP")

    # so that the DBAPI itself knows that the connection has been
    # reset
    dbapi_connection.rollback()

Geändert in Version 2.0.0b3: Zusätzliche Zustandsargumente zum Event PoolEvents.reset() hinzugefügt und außerdem sichergestellt, dass das Event für alle "reset"-Vorkommnisse aufgerufen wird, damit es als Ort für benutzerdefinierte "reset"-Handler geeignet ist. Frühere Schemata, die den Handler PoolEvents.checkin() verwenden, bleiben ebenfalls verwendbar.

Siehe auch

Rücksetzung bei Rückgabe - in der Dokumentation zu Connection Pooling

Festlegen alternativer Suchpfade beim Verbinden

Die PostgreSQL-Variable search_path bezieht sich auf die Liste der Schemanamen, die implizit referenziert werden, wenn eine bestimmte Tabelle oder ein anderes Objekt in einer SQL-Anweisung referenziert wird. Wie im nächsten Abschnitt Remote-Schema-Tabellen-Introspektion und PostgreSQL search_path erläutert, ist SQLAlchemy im Allgemeinen darauf ausgerichtet, diese Variable auf ihrem Standardwert public zu belassen. Um sie jedoch beim automatischen Verbinden auf beliebige Namen oder Namen setzen zu können, kann der Befehl "SET SESSION search_path" für alle Verbindungen eines Pools über den folgenden Event-Handler aufgerufen werden, wie unter Festlegen eines Standard-Schemas für neue Verbindungen erläutert

from sqlalchemy import event
from sqlalchemy import create_engine

engine = create_engine("postgresql+psycopg2://scott:tiger@host/dbname")


@event.listens_for(engine, "connect", insert=True)
def set_search_path(dbapi_connection, connection_record):
    existing_autocommit = dbapi_connection.autocommit
    dbapi_connection.autocommit = True
    cursor = dbapi_connection.cursor()
    cursor.execute("SET SESSION search_path='%s'" % schema_name)
    cursor.close()
    dbapi_connection.autocommit = existing_autocommit

Der Grund, warum das Rezept durch die Verwendung des DBAPI-Attributs .autocommit kompliziert wird, ist, dass wenn die Direktive SET SESSION search_path aufgerufen wird, sie außerhalb des Geltungsbereichs einer Transaktion aufgerufen wird und daher nicht rückgängig gemacht wird, wenn die DBAPI-Verbindung einen Rollback durchführt.

Remote-Schema-Tabellen-Introspektion und PostgreSQL search_path

Zusammenfassung der Best Practices des Abschnitts

Behalten Sie die Variable search_path auf ihrem Standardwert public ohne weitere Schemanamen. Stellen Sie sicher, dass der zum Verbinden verwendete Benutzername **nicht** mit Remote-Schemas übereinstimmt, oder stellen Sie sicher, dass das Token "$user" aus search_path **entfernt** wird. Für andere Schemanamen benennen Sie diese explizit innerhalb von Table-Definitionen. Alternativ bewirkt die Option postgresql_ignore_search_path, dass alle reflektierten Table-Objekte ein Attribut Table.schema zugewiesen bekommen.

Der PostgreSQL-Dialekt kann Tabellen aus jedem Schema reflektieren, wie in Reflektieren von Tabellen aus anderen Schemata beschrieben.

In allen Fällen ist das Erste, was SQLAlchemy bei der Reflektion von Tabellen tut, **das Standard-Schema für die aktuelle Datenbankverbindung zu ermitteln**. Dies geschieht unter Verwendung der PostgreSQL-Funktion current_schema(), die unten anhand einer PostgreSQL-Client-Sitzung (d.h. mit dem Tool psql) veranschaulicht wird.

test=> select current_schema();
current_schema
----------------
public
(1 row)

Oben sehen wir, dass bei einer reinen Installation von PostgreSQL der Standard-Schemaname der Name public ist.

Wenn jedoch Ihr Datenbankbenutzername **dem Namen eines Schemas entspricht**, ist es die Standardeinstellung von PostgreSQL, **diesen Namen als Standard-Schema zu verwenden**. Unten melden wir uns mit dem Benutzernamen scott an. Wenn wir ein Schema namens scott erstellen, **ändert sich implizit das Standard-Schema**

test=> select current_schema();
current_schema
----------------
public
(1 row)

test=> create schema scott;
CREATE SCHEMA
test=> select current_schema();
current_schema
----------------
scott
(1 row)

Das Verhalten von current_schema() leitet sich von der PostgreSQL-Variablen search_path ab, die in neueren PostgreSQL-Versionen standardmäßig auf Folgendes gesetzt ist:

test=> show search_path;
search_path
-----------------
"$user", public
(1 row)

Wo oben die Variable "$user" den aktuellen Benutzernamen als Standard-Schema injiziert, falls vorhanden. Andernfalls wird public verwendet.

Wenn ein Table-Objekt reflektiert wird und es im von der Funktion current_schema() angegebenen Schema vorhanden ist, **ist der der Tabelle zugewiesene Schemaname das Python-Objekt "None"**. Andernfalls wird dem Attribut ".schema" der String-Name dieses Schemas zugewiesen.

In Bezug auf Tabellen, auf die diese Table-Objekte über einen Fremdschlüssel-Constraint verweisen, muss eine Entscheidung getroffen werden, wie das .schema in diesen Remote-Tabellen dargestellt wird, falls dieser Remote-Schemaname auch Mitglied des aktuellen search_path ist.

Standardmäßig imitiert der PostgreSQL-Dialekt das Verhalten, das durch die eingebaute PostgreSQL-Prozedur pg_get_constraintdef() gefördert wird. Diese Funktion gibt eine Beispieldefinition für einen bestimmten Fremdschlüssel-Constraint zurück und lässt den referenzierten Schemanamen aus dieser Definition weg, wenn der Name auch im PostgreSQL-Schema-Suchpfad enthalten ist. Die folgende Interaktion veranschaulicht dieses Verhalten

test=> CREATE TABLE test_schema.referred(id INTEGER PRIMARY KEY);
CREATE TABLE
test=> CREATE TABLE referring(
test(>         id INTEGER PRIMARY KEY,
test(>         referred_id INTEGER REFERENCES test_schema.referred(id));
CREATE TABLE
test=> SET search_path TO public, test_schema;
test=> SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM
test-> pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n
test-> ON n.oid = c.relnamespace
test-> JOIN pg_catalog.pg_constraint r  ON c.oid = r.conrelid
test-> WHERE c.relname='referring' AND r.contype = 'f'
test-> ;
               pg_get_constraintdef
---------------------------------------------------
 FOREIGN KEY (referred_id) REFERENCES referred(id)
(1 row)

Oben haben wir eine Tabelle referred als Mitglied des Remote-Schemas test_schema erstellt. Als wir jedoch test_schema zum PG search_path hinzugefügt und dann pg_get_constraintdef() nach der FOREIGN KEY-Syntax gefragt haben, wurde test_schema nicht in der Ausgabe der Funktion berücksichtigt.

Wenn wir hingegen den Suchpfad zurück auf den typischen Standard von public setzen

test=> SET search_path TO public;
SET

Die gleiche Abfrage gegen pg_get_constraintdef() gibt nun den vollqualifizierten Schemanamen für uns zurück

test=> SELECT pg_catalog.pg_get_constraintdef(r.oid, true) FROM
test-> pg_catalog.pg_class c JOIN pg_catalog.pg_namespace n
test-> ON n.oid = c.relnamespace
test-> JOIN pg_catalog.pg_constraint r  ON c.oid = r.conrelid
test-> WHERE c.relname='referring' AND r.contype = 'f';
                     pg_get_constraintdef
---------------------------------------------------------------
 FOREIGN KEY (referred_id) REFERENCES test_schema.referred(id)
(1 row)

SQLAlchemy verwendet standardmäßig den Rückgabewert von pg_get_constraintdef(), um den Remote-Schemanamen zu ermitteln. Das heißt, wenn unser search_path so gesetzt wäre, dass test_schema enthalten ist, und wir einen Tabellenreflexionsprozess wie folgt aufrufen würden

>>> from sqlalchemy import Table, MetaData, create_engine, text
>>> engine = create_engine("postgresql+psycopg2://scott:tiger@localhost/test")
>>> with engine.connect() as conn:
...     conn.execute(text("SET search_path TO test_schema, public"))
...     metadata_obj = MetaData()
...     referring = Table("referring", metadata_obj, autoload_with=conn)
<sqlalchemy.engine.result.CursorResult object at 0x101612ed0>

Der obige Prozess würde der MetaData.tables-Sammlung die referred-Tabelle **ohne** das Schema zugewiesen liefern

>>> metadata_obj.tables["referred"].schema is None
True

Um das Verhalten der Reflexion so zu ändern, dass das referenzierte Schema unabhängig von der search_path-Einstellung beibehalten wird, verwenden Sie die Option postgresql_ignore_search_path, die als dialektspezifisches Argument sowohl für Table als auch für MetaData.reflect() angegeben werden kann.

>>> with engine.connect() as conn:
...     conn.execute(text("SET search_path TO test_schema, public"))
...     metadata_obj = MetaData()
...     referring = Table(
...         "referring",
...         metadata_obj,
...         autoload_with=conn,
...         postgresql_ignore_search_path=True,
...     )
<sqlalchemy.engine.result.CursorResult object at 0x1016126d0>

Wir werden nun test_schema.referred als Schema-qualifiziert speichern.

>>> metadata_obj.tables["test_schema.referred"].schema
'test_schema'

Siehe auch

Interaktion von Schema-qualifizierter Reflexion mit dem Standard-Schema - Diskussion des Problems aus einer Backend-unabhängigen Perspektive

Der Schema-Suchpfad - auf der PostgreSQL-Website.

INSERT/UPDATE…RETURNING

Der Dialekt unterstützt die INSERT..RETURNING, UPDATE..RETURNING und DELETE..RETURNING-Syntaxen von PG 8.2. INSERT..RETURNING wird standardmäßig für einzelne Zeilen-INSERT-Anweisungen verwendet, um neu generierte Primärschlüssel-Identifikatoren abzurufen. Um eine explizite RETURNING-Klausel anzugeben, verwenden Sie die Methode _UpdateBase.returning() auf Anweisungsebene.

# INSERT..RETURNING
result = (
    table.insert().returning(table.c.col1, table.c.col2).values(name="foo")
)
print(result.fetchall())

# UPDATE..RETURNING
result = (
    table.update()
    .returning(table.c.col1, table.c.col2)
    .where(table.c.name == "foo")
    .values(name="bar")
)
print(result.fetchall())

# DELETE..RETURNING
result = (
    table.delete()
    .returning(table.c.col1, table.c.col2)
    .where(table.c.name == "foo")
)
print(result.fetchall())

INSERT…ON CONFLICT (Upsert)

Ab Version 9.5 erlaubt PostgreSQL "Upserts" (Update oder Insert) von Zeilen in eine Tabelle über die ON CONFLICT-Klausel der INSERT-Anweisung. Eine Kandidatenzeile wird nur eingefügt, wenn diese Zeile keine eindeutigen Constraints verletzt. Im Falle einer Verletzung eines eindeutigen Constraints kann eine sekundäre Aktion erfolgen, die entweder "DO UPDATE" (aktualisiere die Daten in der Zielzeile) oder "DO NOTHING" (überspringe diese Zeile stumm) sein kann.

Konflikte werden anhand bestehender eindeutiger Constraints und Indizes ermittelt. Diese Constraints können entweder anhand ihres Namens, wie in DDL angegeben, identifiziert werden, oder sie können durch Angabe der Spalten und Bedingungen, aus denen die Indizes bestehen, abgeleitet werden.

SQLAlchemy bietet ON CONFLICT-Unterstützung über die PostgreSQL-spezifische Funktion insert(), die die generativen Methoden Insert.on_conflict_do_update() und Insert.on_conflict_do_nothing() bietet.

>>> from sqlalchemy.dialects.postgresql import insert
>>> insert_stmt = insert(my_table).values(
...     id="some_existing_id", data="inserted value"
... )
>>> do_nothing_stmt = insert_stmt.on_conflict_do_nothing(index_elements=["id"])
>>> print(do_nothing_stmt)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO NOTHING
>>> do_update_stmt = insert_stmt.on_conflict_do_update( ... constraint="pk_my_table", set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT ON CONSTRAINT pk_my_table DO UPDATE SET data = %(param_1)s

Siehe auch

INSERT .. ON CONFLICT - in der PostgreSQL-Dokumentation.

Zielspezifikation

Beide Methoden liefern das „Ziel“ des Konflikts entweder über die benannte Einschränkung oder durch Spalteninferenz

  • Das Argument Insert.on_conflict_do_update.index_elements gibt eine Sequenz an, die Spaltennamen als Zeichenketten, Column-Objekte und/oder SQL-Ausdruckselemente enthält, welche einen eindeutigen Index identifizieren würden

    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     index_elements=["id"], set_=dict(data="updated value")
    ... )
    >>> print(do_update_stmt)
    
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s
    >>> do_update_stmt = insert_stmt.on_conflict_do_update( ... index_elements=[my_table.c.id], set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s
  • Bei der Verwendung von Insert.on_conflict_do_update.index_elements zur Ableitung eines Index kann ein partieller Index abgeleitet werden, indem auch die Verwendung des Parameters Insert.on_conflict_do_update.index_where angegeben wird

    >>> stmt = insert(my_table).values(user_email="a@b.com", data="inserted data")
    >>> stmt = stmt.on_conflict_do_update(
    ...     index_elements=[my_table.c.user_email],
    ...     index_where=my_table.c.user_email.like("%@gmail.com"),
    ...     set_=dict(data=stmt.excluded.data),
    ... )
    >>> print(stmt)
    
    INSERT INTO my_table (data, user_email) VALUES (%(data)s, %(user_email)s) ON CONFLICT (user_email) WHERE user_email LIKE %(user_email_1)s DO UPDATE SET data = excluded.data
  • Das Argument Insert.on_conflict_do_update.constraint wird verwendet, um einen Index direkt anzugeben, anstatt ihn abzuleiten. Dies kann der Name einer UNIQUE-Beschränkung, einer PRIMARY KEY-Beschränkung oder eines INDEX sein

    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     constraint="my_table_idx_1", set_=dict(data="updated value")
    ... )
    >>> print(do_update_stmt)
    
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT ON CONSTRAINT my_table_idx_1 DO UPDATE SET data = %(param_1)s
    >>> do_update_stmt = insert_stmt.on_conflict_do_update( ... constraint="my_table_pk", set_=dict(data="updated value") ... ) >>> print(do_update_stmt)
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT ON CONSTRAINT my_table_pk DO UPDATE SET data = %(param_1)s
  • Das Argument Insert.on_conflict_do_update.constraint kann sich auch auf eine SQLAlchemy-Konstruktion beziehen, die eine Einschränkung darstellt, z. B. UniqueConstraint, PrimaryKeyConstraint, Index oder ExcludeConstraint. Bei dieser Verwendung wird, wenn die Einschränkung einen Namen hat, dieser direkt verwendet. Andernfalls, wenn die Einschränkung unbenannt ist, wird die Ableitung verwendet, wobei die Ausdrücke und die optionale WHERE-Klausel der Einschränkung in der Konstruktion ausgeschrieben werden. Diese Verwendung ist besonders praktisch, um auf den benannten oder unbenannten Primärschlüssel einer Table über das Attribut Table.primary_key zu verweisen

    >>> do_update_stmt = insert_stmt.on_conflict_do_update(
    ...     constraint=my_table.primary_key, set_=dict(data="updated value")
    ... )
    >>> print(do_update_stmt)
    
    INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s

Die SET-Klausel

ON CONFLICT...DO UPDATE wird verwendet, um eine vorhandene Zeile zu aktualisieren, wobei jede Kombination von neuen Werten sowie Werten aus dem vorgeschlagenen Einfügen verwendet wird. Diese Werte werden über den Parameter Insert.on_conflict_do_update.set_ angegeben. Dieser Parameter akzeptiert ein Wörterbuch, das direkte Werte für UPDATE enthält

>>> stmt = insert(my_table).values(id="some_id", data="inserted value")
>>> do_update_stmt = stmt.on_conflict_do_update(
...     index_elements=["id"], set_=dict(data="updated value")
... )
>>> print(do_update_stmt)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s

Warnung

Die Methode Insert.on_conflict_do_update() berücksichtigt nicht Python-seitige Standard-UPDATE-Werte oder Generierungsfunktionen, z. B. solche, die über Column.onupdate angegeben werden. Diese Werte werden für einen ON CONFLICT-Stil von UPDATE nicht verwendet, es sei denn, sie werden manuell im Wörterbuch Insert.on_conflict_do_update.set_ angegeben.

Aktualisierung unter Verwendung der ausgeschlossenen INSERT-Werte

Um auf die vorgeschlagene Einfügungszeile zu verweisen, ist der spezielle Alias Insert.excluded als Attribut des Insert-Objekts verfügbar; dieses Objekt ist eine ColumnCollection, die alle Spalten der Zieltabelle alias enthält

>>> stmt = insert(my_table).values(
...     id="some_id", data="inserted value", author="jlh"
... )
>>> do_update_stmt = stmt.on_conflict_do_update(
...     index_elements=["id"],
...     set_=dict(data="updated value", author=stmt.excluded.author),
... )
>>> print(do_update_stmt)
INSERT INTO my_table (id, data, author) VALUES (%(id)s, %(data)s, %(author)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s, author = excluded.author

Zusätzliche WHERE-Kriterien

Die Methode Insert.on_conflict_do_update() akzeptiert auch eine WHERE-Klausel über den Parameter Insert.on_conflict_do_update.where, welche die Zeilen einschränkt, die ein UPDATE erhalten

>>> stmt = insert(my_table).values(
...     id="some_id", data="inserted value", author="jlh"
... )
>>> on_update_stmt = stmt.on_conflict_do_update(
...     index_elements=["id"],
...     set_=dict(data="updated value", author=stmt.excluded.author),
...     where=(my_table.c.status == 2),
... )
>>> print(on_update_stmt)
INSERT INTO my_table (id, data, author) VALUES (%(id)s, %(data)s, %(author)s) ON CONFLICT (id) DO UPDATE SET data = %(param_1)s, author = excluded.author WHERE my_table.status = %(status_1)s

Zeilen überspringen mit DO NOTHING

ON CONFLICT kann verwendet werden, um das Einfügen einer Zeile vollständig zu überspringen, wenn ein Konflikt mit einer eindeutigen Einschränkung oder einer Ausschlussbeschränkung auftritt; unten wird dies mithilfe der Methode Insert.on_conflict_do_nothing() veranschaulicht

>>> stmt = insert(my_table).values(id="some_id", data="inserted value")
>>> stmt = stmt.on_conflict_do_nothing(index_elements=["id"])
>>> print(stmt)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT (id) DO NOTHING

Wenn DO NOTHING verwendet wird, ohne Spalten oder Einschränkungen anzugeben, hat dies zur Folge, dass das INSERT bei jeder Verletzung einer eindeutigen Einschränkung oder einer Ausschlussbeschränkung übersprungen wird

>>> stmt = insert(my_table).values(id="some_id", data="inserted value")
>>> stmt = stmt.on_conflict_do_nothing()
>>> print(stmt)
INSERT INTO my_table (id, data) VALUES (%(id)s, %(data)s) ON CONFLICT DO NOTHING

FROM ONLY …

Der Dialekt unterstützt das Schlüsselwort ONLY von PostgreSQL, um nur eine bestimmte Tabelle in einer Vererbungshierarchie anzusprechen. Dies kann verwendet werden, um die Syntaxen SELECT ... FROM ONLY, UPDATE ONLY ... und DELETE FROM ONLY ... zu erzeugen. Es verwendet den Hinweismechanismus von SQLAlchemy

# SELECT ... FROM ONLY ...
result = table.select().with_hint(table, "ONLY", "postgresql")
print(result.fetchall())

# UPDATE ONLY ...
table.update(values=dict(foo="bar")).with_hint(
    "ONLY", dialect_name="postgresql"
)

# DELETE FROM ONLY ...
table.delete().with_hint("ONLY", dialect_name="postgresql")

PostgreSQL-spezifische Indexoptionen

Mehrere Erweiterungen der Index-Konstruktion sind spezifisch für den PostgreSQL-Dialekt verfügbar.

Abdeckende Indizes

Die Option postgresql_include rendert INCLUDE(colname) für die angegebenen String-Namen

Index("my_index", table.c.x, postgresql_include=["y"])

würde den Index als CREATE INDEX my_index ON table (x) INCLUDE (y) rendern

Beachten Sie, dass diese Funktion PostgreSQL 11 oder neuer erfordert.

Neu in Version 1.4.

Partielle Indizes

Partielle Indizes fügen Kriterien zur Indexdefinition hinzu, sodass der Index auf eine Teilmenge von Zeilen angewendet wird. Diese können auf Index mithilfe des Schlüsselwortarguments postgresql_where angegeben werden

Index("my_index", my_table.c.id, postgresql_where=my_table.c.value > 10)

Operator-Klassen

PostgreSQL erlaubt die Angabe einer Operator-Klasse für jede Spalte eines Index (siehe https://www.postgresql.org/docs/current/interactive/indexes-opclass.html). Die Index-Konstruktion ermöglicht die Angabe dieser über das Schlüsselwortargument postgresql_ops

Index(
    "my_index",
    my_table.c.id,
    my_table.c.data,
    postgresql_ops={"data": "text_pattern_ops", "id": "int4_ops"},
)

Beachten Sie, dass die Schlüssel in den Wörterbüchern postgresql_ops der „Schlüsselname“ der Column sind, d. h. der Name, der für den Zugriff darauf aus der .c-Sammlung der Table verwendet wird, der so konfiguriert werden kann, dass er sich vom tatsächlichen Namen der Spalte unterscheidet, wie er in der Datenbank ausgedrückt wird.

Wenn postgresql_ops auf einen komplexen SQL-Ausdruck wie einen Funktionsaufruf angewendet werden soll, muss er, um auf die Spalte angewendet zu werden, einen Namen erhalten, der im Wörterbuch nach Namen identifiziert wird, z. B.

Index(
    "my_index",
    my_table.c.id,
    func.lower(my_table.c.data).label("data_lower"),
    postgresql_ops={"data_lower": "text_pattern_ops", "id": "int4_ops"},
)

Operator-Klassen werden auch von der ExcludeConstraint-Konstruktion unterstützt, und zwar über den Parameter ExcludeConstraint.ops. Siehe diesen Parameter für Details.

Neu in Version 1.3.21: Unterstützung für Operator-Klassen mit ExcludeConstraint hinzugefügt.

Index-Typen

PostgreSQL bietet verschiedene Index-Typen: B-Tree, Hash, GiST und GIN, sowie die Möglichkeit, eigene zu erstellen (siehe https://www.postgresql.org/docs/current/static/indexes-types.html). Diese können auf Index mit dem Schlüsselwortargument postgresql_using angegeben werden

Index("my_index", my_table.c.data, postgresql_using="gin")

Der Wert, der an das Schlüsselwortargument übergeben wird, wird einfach an den zugrunde liegenden CREATE INDEX-Befehl weitergeleitet, daher muss es sich um einen gültigen Index-Typ für Ihre PostgreSQL-Version handeln.

Index-Speicherparameter

PostgreSQL erlaubt die Einstellung von Speicherparametern für Indizes. Die verfügbaren Speicherparameter hängen von der Indexmethode ab, die vom Index verwendet wird. Speicherparameter können auf Index mit dem Schlüsselwortargument postgresql_with angegeben werden

Index("my_index", my_table.c.data, postgresql_with={"fillfactor": 50})

PostgreSQL erlaubt die Definition des Tablespace, in dem der Index erstellt werden soll. Der Tablespace kann auf Index mit dem Schlüsselwortargument postgresql_tablespace angegeben werden

Index("my_index", my_table.c.data, postgresql_tablespace="my_tablespace")

Beachten Sie, dass dieselbe Option auch für Table verfügbar ist.

Indizes mit CONCURRENTLY

Die PostgreSQL-Indexoption CONCURRENTLY wird unterstützt, indem das Flag postgresql_concurrently an die Index-Konstruktion übergeben wird

tbl = Table("testtbl", m, Column("data", Integer))

idx1 = Index("test_idx1", tbl.c.data, postgresql_concurrently=True)

Die obige Index-Konstruktion rendert DDL für CREATE INDEX, vorausgesetzt, PostgreSQL 8.2 oder höher wird erkannt oder für einen verbindungsunabhängigen Dialekt, als

CREATE INDEX CONCURRENTLY test_idx1 ON testtbl (data)

Für DROP INDEX wird, vorausgesetzt, PostgreSQL 9.2 oder höher wird erkannt oder für einen verbindungsunabhängigen Dialekt, Folgendes ausgegeben

DROP INDEX CONCURRENTLY test_idx1

Bei Verwendung von CONCURRENTLY verlangt die PostgreSQL-Datenbank, dass die Anweisung außerhalb eines Transaktionsblocks aufgerufen wird. Die Python DBAPI erzwingt, dass selbst für eine einzelne Anweisung eine Transaktion vorhanden ist. Um diese Konstruktion zu verwenden, muss der „Autocommit“-Modus der DBAPI verwendet werden

metadata = MetaData()
table = Table("foo", metadata, Column("id", String))
index = Index("foo_idx", table.c.id, postgresql_concurrently=True)

with engine.connect() as conn:
    with conn.execution_options(isolation_level="AUTOCOMMIT"):
        table.create(conn)

PostgreSQL Index Reflektion

Die PostgreSQL-Datenbank erstellt implizit einen UNIQUE INDEX, wann immer die UNIQUE CONSTRAINT-Konstruktion verwendet wird. Beim Inspizieren einer Tabelle mit Inspector berichten Inspector.get_indexes() und Inspector.get_unique_constraints() über diese beiden Konstruktionen getrennt; im Fall des Indexes wird der Schlüssel duplicates_constraint im Índiceintrag vorhanden sein, wenn er als Spiegelung einer Einschränkung erkannt wird. Bei der Reflektion mit Table(..., autoload_with=engine) wird der UNIQUE INDEX nicht in Table.indexes zurückgegeben, wenn er als Spiegelung einer UniqueConstraint in der Table.constraints-Sammlung erkannt wird.

Spezielle Reflektionsoptionen

Der für das PostgreSQL-Backend verwendete Inspector ist eine Instanz von PGInspector, die zusätzliche Methoden bietet

from sqlalchemy import create_engine, inspect

engine = create_engine("postgresql+psycopg2:///test")
insp = inspect(engine)  # will be a PGInspector

print(insp.get_enums())
Objektname Beschreibung

PGInspector

class sqlalchemy.dialects.postgresql.base.PGInspector
method sqlalchemy.dialects.postgresql.base.PGInspector.get_domains(schema: str | None = None) List[ReflectedDomain]

Gibt eine Liste von DOMAIN-Objekten zurück.

Jedes Element ist ein Wörterbuch, das diese Felder enthält

  • name - Name der Domäne

  • schema - der Schema-Name für die Domäne.

  • visible - boolesch, ob diese Domäne im Standard-Suchpfad sichtbar ist.

  • type - der von dieser Domäne definierte Typ.

  • nullable - Gibt an, ob diese Domäne NULL sein kann.

  • default - Der Standardwert der Domäne oder None, wenn die Domäne keinen Standardwert hat.

  • constraints - Eine Liste von Dictionaries mit der von dieser Domäne definierten Einschränkung. Jedes Element enthält zwei Schlüssel: den Namen der Einschränkung und check mit dem Einschränkungstext.

Parameter:

schema – Schema-Name. Wenn None, wird das Standardschema (typischerweise 'public') verwendet. Kann auch auf '*' gesetzt werden, um Domänen für alle Schemata zu laden.

Neu in Version 2.0.

method sqlalchemy.dialects.postgresql.base.PGInspector.get_enums(schema: str | None = None) List[ReflectedEnum]

Gibt eine Liste von ENUM-Objekten zurück.

Jedes Element ist ein Wörterbuch, das diese Felder enthält

  • name - Name des Enums

  • schema - der Schema-Name für das Enum.

  • visible - boolesch, ob dieses Enum im Standard-Suchpfad sichtbar ist.

  • labels - eine Liste von String-Labels, die für das Enum gelten.

Parameter:

schema – Schema-Name. Wenn None, wird das Standardschema (typischerweise 'public') verwendet. Kann auch auf '*' gesetzt werden, um Enums für alle Schemata zu laden.

method sqlalchemy.dialects.postgresql.base.PGInspector.get_foreign_table_names(schema: str | None = None) List[str]

Gibt eine Liste von FOREIGN TABLE-Namen zurück.

Das Verhalten ähnelt dem von Inspector.get_table_names(), außer dass die Liste auf Tabellen beschränkt ist, die einen relkind-Wert von f melden.

method sqlalchemy.dialects.postgresql.base.PGInspector.get_table_oid(table_name: str, schema: str | None = None) int

Gibt die OID für den angegebenen Tabellennamen zurück.

Parameter:
  • table_name – Zeichenkettenname der Tabelle. Für spezielle Anführungszeichen verwenden Sie quoted_name.

  • schema – Zeichenketten-Schema-Name; wenn weggelassen, wird das Standardschema der Datenbankverbindung verwendet. Für spezielle Anführungszeichen verwenden Sie quoted_name.

method sqlalchemy.dialects.postgresql.base.PGInspector.has_type(type_name: str, schema: str | None = None, **kw: Any) bool

Gibt zurück, ob die Datenbank den angegebenen Typ im angegebenen Schema hat.

Parameter:
  • type_name – der zu prüfende Typ.

  • schema – Schema-Name. Wenn None, wird das Standardschema (typischerweise 'public') verwendet. Kann auch auf '*' gesetzt werden, um in allen Schemata zu prüfen.

Neu in Version 2.0.

PostgreSQL-Tabellenoptionen

Mehrere Optionen für CREATE TABLE werden direkt vom PostgreSQL-Dialekt in Verbindung mit der Table-Konstruktion unterstützt

  • INHERITS:

    Table("some_table", metadata, ..., postgresql_inherits="some_supertable")
    
    Table("some_table", metadata, ..., postgresql_inherits=("t1", "t2", ...))
  • ON COMMIT:

    Table("some_table", metadata, ..., postgresql_on_commit="PRESERVE ROWS")
  • PARTITION BY:

    Table(
        "some_table",
        metadata,
        ...,
        postgresql_partition_by="LIST (part_column)",
    )

    Neu in Version 1.2.6.

  • TABLESPACE:

    Table("some_table", metadata, ..., postgresql_tablespace="some_tablespace")

    Die obige Option ist auch auf der Index-Konstruktion verfügbar.

  • USING:

    Table("some_table", metadata, ..., postgresql_using="heap")

    Neu in Version 2.0.26.

  • WITH OIDS:

    Table("some_table", metadata, ..., postgresql_with_oids=True)
  • WITHOUT OIDS:

    Table("some_table", metadata, ..., postgresql_with_oids=False)

Siehe auch

PostgreSQL CREATE TABLE-Optionen - in der PostgreSQL-Dokumentation.

PostgreSQL-Einschränkungsoptionen

Die folgenden Optionen werden vom PostgreSQL-Dialekt in Verbindung mit ausgewählten Einschränkungskonstruktionen unterstützt

  • NOT VALID: Diese Option gilt für CHECK- und FOREIGN KEY-Einschränkungen, wenn die Einschränkung einer vorhandenen Tabelle über ALTER TABLE hinzugefügt wird, und hat zur Folge, dass bestehende Zeilen während der ALTER-Operation gegen die hinzugefügte Einschränkung nicht gescannt werden.

    Bei Verwendung eines SQL-Migrationstools wie Alembic, das ALTER TABLE-Konstrukte rendert, kann das Argument postgresql_not_valid als zusätzliches Schlüsselwortargument innerhalb der Operation, die die Einschränkung erstellt, angegeben werden, wie im folgenden Alembic-Beispiel:

    def update():
        op.create_foreign_key(
            "fk_user_address",
            "address",
            "user",
            ["user_id"],
            ["id"],
            postgresql_not_valid=True,
        )

    Das Schlüsselwort wird letztendlich direkt von den CheckConstraint, ForeignKeyConstraint und ForeignKey Konstrukten akzeptiert; bei Verwendung eines Tools wie Alembic werden Dialekt-spezifische Schlüsselwortargumente von den Migrationsoperationsdirektiven an diese Konstrukte weitergeleitet.

    CheckConstraint("some_field IS NOT NULL", postgresql_not_valid=True)
    
    ForeignKeyConstraint(
        ["some_id"], ["some_table.some_id"], postgresql_not_valid=True
    )

    Neu in Version 1.4.32.

    Siehe auch

    PostgreSQL ALTER TABLE Optionen - in der PostgreSQL-Dokumentation.

Tabellenwerte, Tabellen- und spaltenwertige Funktionen, Zeilen- und Tupelobjekte

PostgreSQL nutzt moderne SQL-Formen wie tabellenwertige Funktionen, Tabellen und Zeilen als Werte intensiv. Diese Konstrukte werden häufig als Teil der PostgreSQL-Unterstützung für komplexe Datentypen wie JSON, ARRAY und andere Datentypen verwendet. Die SQL-Ausdruckssprache von SQLAlchemy verfügt über native Unterstützung für die meisten tabellenwertigen und zeilenwertigen Formen.

Tabellenwertige Funktionen

Viele integrierte PostgreSQL-Funktionen sind dafür gedacht, in der FROM-Klausel einer SELECT-Anweisung verwendet zu werden und können Tabellenzeilen oder Mengen von Tabellenzeilen zurückgeben. Ein großer Teil der PostgreSQL JSON-Funktionen zum Beispiel, wie json_array_elements(), json_object_keys(), json_each_text(), json_each(), json_to_record(), json_populate_recordset(), verwenden solche Formen. Diese Klassen von SQL-Funktionsaufruf-Formen in SQLAlchemy sind über die Methode FunctionElement.table_valued() in Verbindung mit Function-Objekten, die aus dem func-Namespace generiert werden, verfügbar.

Beispiele aus der Referenzdokumentation von PostgreSQL folgen unten

  • json_each():

    >>> from sqlalchemy import select, func
    >>> stmt = select(
    ...     func.json_each('{"a":"foo", "b":"bar"}').table_valued("key", "value")
    ... )
    >>> print(stmt)
    
    SELECT anon_1.key, anon_1.value FROM json_each(:json_each_1) AS anon_1
  • json_populate_record():

    >>> from sqlalchemy import select, func, literal_column
    >>> stmt = select(
    ...     func.json_populate_record(
    ...         literal_column("null::myrowtype"), '{"a":1,"b":2}'
    ...     ).table_valued("a", "b", name="x")
    ... )
    >>> print(stmt)
    
    SELECT x.a, x.b FROM json_populate_record(null::myrowtype, :json_populate_record_1) AS x
  • json_to_record() - diese Form verwendet eine PostgreSQL-spezifische Form von abgeleiteten Spalten im Alias, wobei wir column() Elemente mit Typen verwenden können, um diese zu erzeugen. Die Methode FunctionElement.table_valued() erzeugt ein TableValuedAlias Konstrukt, und die Methode TableValuedAlias.render_derived() Methode richtet die Spezifikation der abgeleiteten Spalten ein.

    >>> from sqlalchemy import select, func, column, Integer, Text
    >>> stmt = select(
    ...     func.json_to_record('{"a":1,"b":[1,2,3],"c":"bar"}')
    ...     .table_valued(
    ...         column("a", Integer),
    ...         column("b", Text),
    ...         column("d", Text),
    ...     )
    ...     .render_derived(name="x", with_types=True)
    ... )
    >>> print(stmt)
    
    SELECT x.a, x.b, x.d FROM json_to_record(:json_to_record_1) AS x(a INTEGER, b TEXT, d TEXT)
  • WITH ORDINALITY - Teil des SQL-Standards, WITH ORDINALITY fügt einen ordinalen Zähler zur Ausgabe einer Funktion hinzu und wird von einer begrenzten Anzahl von PostgreSQL-Funktionen akzeptiert, darunter unnest() und generate_series(). Die Methode FunctionElement.table_valued() akzeptiert zu diesem Zweck einen Schlüsselwortparameter with_ordinality, der den String-Namen akzeptiert, der der "Ordinalitäts"-Spalte zugewiesen wird.

    >>> from sqlalchemy import select, func
    >>> stmt = select(
    ...     func.generate_series(4, 1, -1)
    ...     .table_valued("value", with_ordinality="ordinality")
    ...     .render_derived()
    ... )
    >>> print(stmt)
    
    SELECT anon_1.value, anon_1.ordinality FROM generate_series(:generate_series_1, :generate_series_2, :generate_series_3) WITH ORDINALITY AS anon_1(value, ordinality)

Neu ab Version 1.4.0b2.

Spaltenwertige Funktionen

Ähnlich wie bei der tabellenwertigen Funktion ist eine spaltenwertige Funktion in der FROM-Klausel vorhanden, liefert sich aber selbst als einzelnen Skalarwert an die Spaltenklausel. PostgreSQL-Funktionen wie json_array_elements(), unnest() und generate_series() können diese Form verwenden. Spaltenwertige Funktionen sind über die Methode FunctionElement.column_valued() von FunctionElement verfügbar.

  • json_array_elements():

    >>> from sqlalchemy import select, func
    >>> stmt = select(
    ...     func.json_array_elements('["one", "two"]').column_valued("x")
    ... )
    >>> print(stmt)
    
    SELECT x FROM json_array_elements(:json_array_elements_1) AS x
  • unnest() - um ein PostgreSQL ARRAY-Literal zu erzeugen, kann das array() Konstrukt verwendet werden.

    >>> from sqlalchemy.dialects.postgresql import array
    >>> from sqlalchemy import select, func
    >>> stmt = select(func.unnest(array([1, 2])).column_valued())
    >>> print(stmt)
    
    SELECT anon_1 FROM unnest(ARRAY[%(param_1)s, %(param_2)s]) AS anon_1

    Die Funktion kann natürlich auch auf eine vorhandene, tabellengebundene Spalte vom Typ ARRAY angewendet werden.

    >>> from sqlalchemy import table, column, ARRAY, Integer
    >>> from sqlalchemy import select, func
    >>> t = table("t", column("value", ARRAY(Integer)))
    >>> stmt = select(func.unnest(t.c.value).column_valued("unnested_value"))
    >>> print(stmt)
    
    SELECT unnested_value FROM unnest(t.value) AS unnested_value

Zeilentypen

Die integrierte Unterstützung für das Rendern von ROW kann mit func.ROW im sqlalchemy.func Namespace oder durch Verwendung des tuple_() Konstrukts angenähert werden.

>>> from sqlalchemy import table, column, func, tuple_
>>> t = table("t", column("id"), column("fk"))
>>> stmt = (
...     t.select()
...     .where(tuple_(t.c.id, t.c.fk) > (1, 2))
...     .where(func.ROW(t.c.id, t.c.fk) < func.ROW(3, 7))
... )
>>> print(stmt)
SELECT t.id, t.fk FROM t WHERE (t.id, t.fk) > (:param_1, :param_2) AND ROW(t.id, t.fk) < ROW(:ROW_1, :ROW_2)

An Funktionen übergebene Tabellentypen

PostgreSQL unterstützt die Übergabe einer Tabelle als Argument an eine Funktion, was als „Record“-Typ bekannt ist. SQLAlchemy FromClause-Objekte wie Table unterstützen diese spezielle Form über die Methode FromClause.table_valued(), die mit der Methode FunctionElement.table_valued() vergleichbar ist, mit dem Unterschied, dass die Sammlung von Spalten bereits durch die des FromClause selbst festgelegt ist.

>>> from sqlalchemy import table, column, func, select
>>> a = table("a", column("id"), column("x"), column("y"))
>>> stmt = select(func.row_to_json(a.table_valued()))
>>> print(stmt)
SELECT row_to_json(a) AS row_to_json_1 FROM a

Neu ab Version 1.4.0b2.

ARRAY-Typen

Der PostgreSQL-Dialekt unterstützt Arrays, sowohl als mehrdimensionale Spaltentypen als auch als Array-Literale.

JSON-Typen

Der PostgreSQL-Dialekt unterstützt sowohl JSON- als auch JSONB-Datentypen, einschließlich der nativen Unterstützung von psycopg2 und der Unterstützung für alle speziellen Operatoren von PostgreSQL.

HSTORE-Typ

Der PostgreSQL HSTORE-Typ sowie HSTORE-Literale werden unterstützt.

ENUM-Typen

PostgreSQL verfügt über eine unabhängig erstellbare TYPE-Struktur, die zur Implementierung eines Aufzählungstyps verwendet wird. Dieser Ansatz bringt erhebliche Komplexität auf der SQLAlchemy-Seite mit sich, was die Zeitpunkte betrifft, zu denen dieser Typ ERSTELLT und GELÖSCHT werden sollte. Das Typobjekt ist auch eine unabhängig reflektierbare Entität. Die folgenden Abschnitte sollten konsultiert werden:

Verwendung von ENUM mit ARRAY

Die Kombination von ENUM und ARRAY wird derzeit nicht direkt von Backend-DBAPIs unterstützt. Vor SQLAlchemy 1.3.17 war ein spezieller Workaround erforderlich, um diese Kombination zu ermöglichen, wie unten beschrieben.

Geändert in Version 1.3.17: Die Kombination von ENUM und ARRAY wird jetzt direkt von der Implementierung von SQLAlchemy gehandhabt, ohne dass Workarounds erforderlich sind.

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

Z. B.

Table(
    "mydata",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", ArrayOfEnum(ENUM("a", "b", "c", name="myenum"))),
)

Dieser Typ ist nicht als integrierter Typ enthalten, da er mit einem DBAPI, der plötzlich beschließt, ARRAY von ENUM direkt in einer neuen Version zu unterstützen, inkompatibel wäre.

Verwendung von JSON/JSONB mit ARRAY

Ähnlich wie bei der Verwendung von ENUM benötigten wir vor SQLAlchemy 1.3.17 für ein ARRAY von JSON/JSONB das Rendern des entsprechenden CAST. Aktuelle psycopg2-Treiber verarbeiten das Ergebnis korrekt ohne spezielle Schritte.

Geändert in Version 1.3.17: Die Kombination von JSON/JSONB und ARRAY wird jetzt direkt von der Implementierung von SQLAlchemy gehandhabt, ohne dass Workarounds erforderlich sind.

class CastingArray(ARRAY):
    def bind_expression(self, bindvalue):
        return sa.cast(bindvalue, self)

Z. B.

Table(
    "mydata",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", CastingArray(JSONB)),
)

Bereichs- und Multibereichtypen

PostgreSQL-Bereichs- und Multibereichtypen werden für die Dialekte psycopg, pg8000 und asyncpg unterstützt; der psycopg2-Dialekt unterstützt nur die Bereichstypen.

Neu in Version 2.0.17: Unterstützung für Bereiche und Multibereiche für den pg8000-Dialekt hinzugefügt. pg8000 1.29.8 oder neuer ist erforderlich.

An die Datenbank übergebene Datenwerte können als Zeichenfolgen oder unter Verwendung des Range-Datenobjekts übergeben werden.

Neu in Version 2.0: Hinzugefügt des Backend-agnostischen Range-Objekts zur Angabe von Bereichen. Die psycopg2-spezifischen Bereichsklassen werden nicht mehr verfügbar gemacht und nur intern von diesem speziellen Dialekt verwendet.

Z. B. ein Beispiel für ein vollständig typisiertes Modell, das den TSRANGE-Datentyp verwendet.

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)

Um Daten für die obige during-Spalte darzustellen, ist der Range-Typ eine einfache Dataclass, die die Grenzen des Bereichs darstellt. Unten wird ein INSERT einer Zeile in die obige room_booking-Tabelle gezeigt.

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()

Die Auswahl aus einer beliebigen Bereichsspalte gibt auch Range-Objekte zurück, wie angegeben.

from sqlalchemy import select

with Session(engine) as session:
    for row in session.execute(select(RoomBooking.during)):
        print(row)

Die verfügbaren Bereichsdatentypen sind wie folgt:

Objektname Beschreibung

Bereich

Stellt einen PostgreSQL-Bereich dar.

Klasse sqlalchemy.dialects.postgresql.Range

Stellt einen PostgreSQL-Bereich dar.

Z. B.

r = Range(10, 50, bounds="()")

Die Aufrufweise ähnelt der von psycopg und psycopg2, teilweise um eine einfachere Migration von früheren SQLAlchemy-Versionen zu ermöglichen, die diese Objekte direkt verwendet haben.

Parameter:
  • lower – Untere Schranke, oder None

  • upper – Obere Schranke, oder None

  • bounds – Nur-Schlüsselwort, optionaler Zeichenfolgenwert, der einer der folgenden ist: "()", "[)", "(]", "[]". Standard ist "[)".

  • empty – Nur-Schlüsselwort, optionaler boolescher Wert, der angibt, dass dies ein „leerer“ Bereich ist.

Neu in Version 2.0.

Klassensignatur

Klasse sqlalchemy.dialects.postgresql.Range (typing.Generic)

Methode sqlalchemy.dialects.postgresql.Range.__eq__(other: Any) bool

Vergleicht diesen Bereich mit dem anderen unter Berücksichtigung der Inklusivität der Schranken. Gibt True zurück, wenn sie gleich sind.

Methode sqlalchemy.dialects.postgresql.Range.adjacent_to(other: Range[_T]) bool

Ermittelt, ob dieser Bereich an den anderen angrenzt.

Methode sqlalchemy.dialects.postgresql.Range.contained_by(other: Range[_T]) bool

Ermittelt, ob dieser Bereich vom anderen umschlossen wird.

Methode sqlalchemy.dialects.postgresql.Range.contains(value: _T | Range[_T]) bool

Ermittelt, ob dieser Bereich den Wert enthält.

Methode sqlalchemy.dialects.postgresql.Range.difference(other: Range[_T]) Range[_T]

Berechnet die Differenz zwischen diesem Bereich und dem anderen.

Dies löst eine ValueError Ausnahme aus, wenn die beiden Bereiche „disjunkt“ sind, d.h. weder angrenzend noch überlappend.

Methode sqlalchemy.dialects.postgresql.Range.intersection(other: Range[_T]) Range[_T]

Berechnet die Schnittmenge dieses Bereichs mit dem anderen.

Neu in Version 2.0.10.

Attribut sqlalchemy.dialects.postgresql.Range.is_empty

Ein Synonym für das Attribut 'empty'.

Attribut sqlalchemy.dialects.postgresql.Range.isempty

Ein Synonym für das Attribut 'empty'.

Attribut sqlalchemy.dialects.postgresql.Range.lower: _T | None

die untere Schranke

Attribut sqlalchemy.dialects.postgresql.Range.lower_inc

Gibt True zurück, wenn die untere Schranke inklusiv ist.

Attribut sqlalchemy.dialects.postgresql.Range.lower_inf

Gibt True zurück, wenn dieser Bereich nicht leer ist und die untere Schranke unendlich ist.

Methode sqlalchemy.dialects.postgresql.Range.not_extend_left_of(other: Range[_T]) bool

Ermittelt, ob dieser Bereich nicht über die linke Seite des anderen hinausreicht.

Methode sqlalchemy.dialects.postgresql.Range.not_extend_right_of(other: Range[_T]) bool

Ermittelt, ob dieser Bereich nicht über die rechte Seite des anderen hinausreicht.

Methode sqlalchemy.dialects.postgresql.Range.overlaps(other: Range[_T]) bool

Ermittelt, ob dieser Bereich mit dem anderen überlappt.

Methode sqlalchemy.dialects.postgresql.Range.strictly_left_of(other: Range[_T]) bool

Ermittelt, ob dieser Bereich vollständig links vom anderen liegt.

methode sqlalchemy.dialects.postgresql.Range.strictly_right_of(other: Range[_T]) bool

Bestimmt, ob dieser Bereich vollständig rechts von other liegt.

methode sqlalchemy.dialects.postgresql.Range.union(other: Range[_T]) Range[_T]

Berechnet die Vereinigung dieses Bereichs mit other.

Dies löst eine ValueError Ausnahme aus, wenn die beiden Bereiche „disjunkt“ sind, d.h. weder angrenzend noch überlappend.

attribut sqlalchemy.dialects.postgresql.Range.upper: _T | None

die obere Grenze

attribut sqlalchemy.dialects.postgresql.Range.upper_inc

Gibt True zurück, wenn die obere Grenze inklusiv ist.

attribut sqlalchemy.dialects.postgresql.Range.upper_inf

Gibt True zurück, wenn dieser Bereich nicht leer ist und die obere Grenze unendlich ist.

Multiranges

Multiranges werden ab PostgreSQL 14 unterstützt. Die Multirange-Datentypen von SQLAlchemy verarbeiten Listen von Range-Typen.

Multiranges werden **nur** mit den Dialekten psycopg, asyncpg und pg8000 unterstützt. Der psycopg2-Dialekt, der der Standard-Dialekt von SQLAlchemy für postgresql ist, unterstützt **keine** Multirange-Datentypen.

Neu in Version 2.0: Unterstützung für MULTIRANGE-Datentypen hinzugefügt. SQLAlchemy repräsentiert einen Multirange-Wert als Liste von Range-Objekten.

Neu in Version 2.0.17: Multirange-Unterstützung für den pg8000-Dialekt hinzugefügt. pg8000 1.29.8 oder höher ist erforderlich.

Neu in Version 2.0.26: Sequenz MultiRange hinzugefügt.

Das folgende Beispiel illustriert die Verwendung des TSMULTIRANGE-Datentyps

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]
    added: Mapped[datetime]
    in_session_periods: Mapped[List[Range[datetime]]] = mapped_column(TSMULTIRANGE)

Einfügen und Abfragen eines Datensatzes illustrieren

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}")

Hinweis

Im obigen Beispiel erkennen die von der ORM verarbeiteten Listen von Range-Typen automatisch keine Änderungen innerhalb einer bestimmten Listenwerte; um Listenwerte mit der ORM zu aktualisieren, weisen Sie dem Attribut entweder eine neue Liste zu oder verwenden Sie den Modifikator des Typs MutableList. Siehe den Abschnitt Mutationsverfolgung für Hintergrundinformationen.

Verwendung einer Multirange-Sequenz zur Ableitung des Multirange-Typs

Bei Verwendung einer Multirange als Literal ohne Angabe des Typs kann die Hilfssequenz MultiRange verwendet werden.

from sqlalchemy import literal
from sqlalchemy.dialects.postgresql import MultiRange

with Session(engine) as session:
    stmt = select(EventCalendar).where(
        EventCalendar.added.op("<@")(
            MultiRange(
                [
                    Range(datetime(2023, 1, 1), datetime(2013, 3, 31)),
                    Range(datetime(2023, 7, 1), datetime(2013, 9, 30)),
                ]
            )
        )
    )
    in_range = session.execute(stmt).all()

with engine.connect() as conn:
    row = conn.scalar(select(literal(MultiRange([Range(2, 4)]))))
    print(f"{row.lower} -> {row.upper}")

Die Verwendung einer einfachen list anstelle von MultiRange würde erfordern, den Typ des Literalwerts manuell auf den entsprechenden Multirange-Typ zu setzen.

Neu in Version 2.0.26: Sequenz MultiRange hinzugefügt.

Die verfügbaren Multirange-Datentypen sind die folgenden:

Netzwerkdatentypen

Die enthaltenen Netzwerkdatentypen sind INET, CIDR und MACADDR.

Für die Datentypen INET und CIDR ist eine bedingte Unterstützung verfügbar, um Python-Objekte von ipaddress zu senden und abzurufen, einschließlich ipaddress.IPv4Network, ipaddress.IPv6Network, ipaddress.IPv4Address und ipaddress.IPv6Address. Diese Unterstützung ist derzeit das **Standardverhalten der DBAPI selbst und variiert je nach DBAPI. SQLAlchemy implementiert noch keine eigene Logik zur Konvertierung von Netzwerkadressen**.

  • Die Dialekte psycopg und asyncpg unterstützen diese Datentypen vollständig; Objekte aus der ipaddress-Familie werden standardmäßig in Zeilen zurückgegeben.

  • Der psycopg2-Dialekt sendet und empfängt nur Zeichenketten.

  • Der pg8000-Dialekt unterstützt ipaddress.IPv4Address und ipaddress.IPv6Address-Objekte für den INET-Datentyp, verwendet aber Zeichenketten für CIDR-Typen.

Um **alle oben genannten DBAPIs auf die Rückgabe von Zeichenketten zu normalisieren**, verwenden Sie den Parameter native_inet_types und übergeben Sie den Wert False.

e = create_engine(
    "postgresql+psycopg://scott:tiger@host/dbname", native_inet_types=False
)

Mit dem obigen Parameter deaktivieren die Dialekte psycopg, asyncpg und pg8000 die Anpassung dieser Typen durch die DBAPI und geben nur Zeichenketten zurück, was dem Verhalten des älteren psycopg2-Dialekts entspricht.

Der Parameter kann auch auf True gesetzt werden, was dazu führt, dass für Backends, die keine oder noch keine vollständige Konvertierung von Zeilen in Python ipaddress-Datentypen unterstützen, eine NotImplementedError ausgelöst wird (derzeit psycopg2 und pg8000).

Neu in Version 2.0.18: - hinzugefügt den Parameter native_inet_types.

PostgreSQL-Datentypen

Wie bei allen SQLAlchemy-Dialekten sind alle GROSSBUCHSTABEN-Typen, die bekanntermaßen mit PostgreSQL gültig sind, von der obersten Ebene des Dialekts importierbar, unabhängig davon, ob sie aus sqlalchemy.types oder aus dem lokalen Dialekt stammen.

from sqlalchemy.dialects.postgresql import (
    ARRAY,
    BIGINT,
    BIT,
    BOOLEAN,
    BYTEA,
    CHAR,
    CIDR,
    CITEXT,
    DATE,
    DATEMULTIRANGE,
    DATERANGE,
    DOMAIN,
    DOUBLE_PRECISION,
    ENUM,
    FLOAT,
    HSTORE,
    INET,
    INT4MULTIRANGE,
    INT4RANGE,
    INT8MULTIRANGE,
    INT8RANGE,
    INTEGER,
    INTERVAL,
    JSON,
    JSONB,
    JSONPATH,
    MACADDR,
    MACADDR8,
    MONEY,
    NUMERIC,
    NUMMULTIRANGE,
    NUMRANGE,
    OID,
    REAL,
    REGCLASS,
    REGCONFIG,
    SMALLINT,
    TEXT,
    TIME,
    TIMESTAMP,
    TSMULTIRANGE,
    TSQUERY,
    TSRANGE,
    TSTZMULTIRANGE,
    TSTZRANGE,
    TSVECTOR,
    UUID,
    VARCHAR,
)

Typen, die spezifisch für PostgreSQL sind oder PostgreSQL-spezifische Konstruktorargumente haben, sind die folgenden:

Objektname Beschreibung

AbstractMultiRange

Basis für PostgreSQL MULTIRANGE-Typen.

AbstractRange

Basisklasse für einzelne und multiple Range-SQL-Typen.

AbstractSingleRange

Basis für PostgreSQL RANGE-Typen.

ARRAY

PostgreSQL ARRAY-Typ.

BIT

BYTEA

CIDR

CITEXT

Stellt den PostgreSQL CITEXT-Typ bereit.

DATEMULTIRANGE

Stellt den PostgreSQL DATEMULTIRANGE-Typ dar.

DATERANGE

Stellt den PostgreSQL DATERANGE-Typ dar.

DOMAIN

Stellt den PostgreSQL DOMAIN-Typ dar.

ENUM

PostgreSQL ENUM-Typ.

HSTORE

Stellt den PostgreSQL HSTORE-Typ dar.

INET

INT4MULTIRANGE

Stellt den PostgreSQL INT4MULTIRANGE-Typ dar.

INT4RANGE

Stellt den PostgreSQL INT4RANGE-Typ dar.

INT8MULTIRANGE

Stellt den PostgreSQL INT8MULTIRANGE-Typ dar.

INT8RANGE

Stellt den PostgreSQL INT8RANGE-Typ dar.

INTERVAL

PostgreSQL INTERVAL-Typ.

JSON

Stellt den PostgreSQL JSON-Typ dar.

JSONB

Stellt den PostgreSQL JSONB-Typ dar.

JSONPATH

JSON-Pfad-Typ.

MACADDR

MACADDR8

MONEY

Stellt den PostgreSQL MONEY-Typ bereit.

MultiRange

Repräsentiert eine Multirange-Sequenz.

NUMMULTIRANGE

Stellt den PostgreSQL NUMMULTIRANGE-Typ dar.

NUMRANGE

Stellt den PostgreSQL NUMRANGE-Typ dar.

OID

Stellt den PostgreSQL OID-Typ bereit.

REGCLASS

Stellt den PostgreSQL REGCLASS-Typ bereit.

REGCONFIG

Stellt den PostgreSQL REGCONFIG-Typ bereit.

TIME

PostgreSQL TIME-Typ.

TIMESTAMP

Stellt den PostgreSQL TIMESTAMP-Typ bereit.

TSMULTIRANGE

Stellt den PostgreSQL TSRANGE-Typ dar.

TSQUERY

Stellt den PostgreSQL TSQUERY-Typ bereit.

TSRANGE

Stellt den PostgreSQL TSRANGE-Typ dar.

TSTZMULTIRANGE

Stellt den PostgreSQL TSTZRANGE-Typ dar.

TSTZRANGE

Stellt den PostgreSQL TSTZRANGE-Typ dar.

TSVECTOR

Der TSVECTOR-Typ implementiert den PostgreSQL-Textsuchtyp TSVECTOR.

klasse sqlalchemy.dialects.postgresql.AbstractRange

Basisklasse für einzelne und multiple Range-SQL-Typen.

klasse comparator_factory

Definiert Vergleichsoperationen für Rangtypen.

Klassensignatur

Klasse sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory (sqlalchemy.types.Comparator)

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.adjacent_to(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn der Bereich in der Spalte an den Bereich im Operanden angrenzt.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.contained_by(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn die Spalte vom rechten Operanden enthalten ist.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.contains(other: Any, **kw: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn der rechte Operand, der ein Element oder ein Bereich sein kann, von der Spalte enthalten ist.

kwargs können von diesem Operator ignoriert werden, sind aber für die API-Konformität erforderlich.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.difference(other: Any) ColumnElement[bool]

Bereichsausdruck. Gibt die Vereinigung der beiden Bereiche zurück. Löst eine Ausnahme aus, wenn der resultierende Bereich nicht zusammenhängend ist.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.intersection(other: Any) ColumnElement[Range[_T]]

Bereichsausdruck. Gibt die Schnittmenge der beiden Bereiche zurück. Löst eine Ausnahme aus, wenn der resultierende Bereich nicht zusammenhängend ist.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.not_extend_left_of(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn der Bereich in der Spalte nicht weiter links als der Bereich im Operanden liegt.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.not_extend_right_of(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn der Bereich in der Spalte nicht weiter rechts als der Bereich im Operanden liegt.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.overlaps(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn die Spalte den rechten Operanden überlappt (gemeinsame Punkte hat).

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.strictly_left_of(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn die Spalte streng links vom rechten Operanden liegt.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.strictly_right_of(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Gibt True zurück, wenn die Spalte streng rechts vom rechten Operanden liegt.

methode sqlalchemy.dialects.postgresql.AbstractRange.comparator_factory.union(other: Any) ColumnElement[bool]

Bereichsausdruck. Gibt die Vereinigung der beiden Bereiche zurück. Löst eine Ausnahme aus, wenn der resultierende Bereich nicht zusammenhängend ist.

klasse sqlalchemy.dialects.postgresql.AbstractSingleRange

Basis für PostgreSQL RANGE-Typen.

Dies sind Typen, die ein einzelnes Range-Objekt zurückgeben.

klasse sqlalchemy.dialects.postgresql.AbstractMultiRange

Basis für PostgreSQL MULTIRANGE-Typen.

Dies sind Typen, die eine Sequenz von Range-Objekten zurückgeben.

klasse sqlalchemy.dialects.postgresql.ARRAY

PostgreSQL ARRAY-Typ.

Der ARRAY-Typ wird auf die gleiche Weise konstruiert wie der Kern-ARRAY-Typ; ein Mitgliedstyp ist erforderlich, und eine Anzahl von Dimensionen wird empfohlen, wenn der Typ für mehr als eine Dimension verwendet werden soll.

from sqlalchemy.dialects import postgresql

mytable = Table(
    "mytable",
    metadata,
    Column("data", postgresql.ARRAY(Integer, dimensions=2)),
)

Der ARRAY-Typ bietet alle Operationen, die auf dem Kern-ARRAY-Typ definiert sind, einschließlich Unterstützung für „Dimensionen“, indizierten Zugriff und einfache Übereinstimmungen wie Comparator.any() und Comparator.all(). Die Klasse ARRAY bietet auch PostgreSQL-spezifische Methoden für Containment-Operationen, einschließlich Comparator.contains() Comparator.contained_by() und Comparator.overlap(), z. B.:

mytable.c.data.contains([1, 2])

Der indizierte Zugriff ist standardmäßig einstellig, um dem von PostgreSQL zu entsprechen; für nullbasierten indizierten Zugriff setzen Sie ARRAY.zero_indexes.

Zusätzlich funktioniert der ARRAY-Typ nicht direkt in Verbindung mit dem ENUM-Typ. Eine Umgehungslösung finden Sie im speziellen Typ unter Verwendung von ENUM mit ARRAY.

Erkennung von Änderungen in ARRAY-Spalten bei Verwendung der ORM

Der ARRAY-Typ erkennt bei Verwendung mit der SQLAlchemy ORM keine In-place-Mutationen des Arrays. Um diese zu erkennen, muss die Erweiterung sqlalchemy.ext.mutable verwendet werden, unter Verwendung der Klasse MutableList.

from sqlalchemy.dialects.postgresql import ARRAY
from sqlalchemy.ext.mutable import MutableList


class SomeOrmClass(Base):
    # ...

    data = Column(MutableList.as_mutable(ARRAY(Integer)))

Diese Erweiterung ermöglicht „In-place“-Änderungen wie .append(), um Ereignisse zu erzeugen, die von der Unit of Work erkannt werden. Beachten Sie, dass Änderungen an Elementen **innerhalb** des Arrays, einschließlich Arrays, die in-place mutiert werden, **nicht** erkannt werden.

Alternativ löst die Zuweisung eines neuen Array-Werts zu einem ORM-Element, das den alten ersetzt, immer ein Änderungsereignis aus.

Siehe auch

ARRAY - Basis-Array-Typ

array - erzeugt einen Literal-Array-Wert.

methode sqlalchemy.dialects.postgresql.ARRAY.__init__(item_type: _TypeEngineArgument[Any], as_tuple: bool = False, dimensions: int | None = None, zero_indexes: bool = False)

Konstruiert ein ARRAY.

Z. B.

Column("myarray", ARRAY(Integer))

Argumente sind

Parameter:
  • item_type – Der Datentyp der Elemente dieses Arrays. Beachten Sie, dass die Dimensionalität hier irrelevant ist. Mehrdimensionale Arrays wie INTEGER[][] werden als ARRAY(Integer) konstruiert, nicht als ARRAY(ARRAY(Integer)) oder ähnliches.

  • as_tuple=False – Gibt an, ob die Ergebnisse als Tupel statt Listen zurückgegeben werden sollen. DBAPIs wie psycopg2 geben standardmäßig Listen zurück. Wenn Tupel zurückgegeben werden, sind die Ergebnisse hashbar.

  • dimensions – Wenn nicht None, nimmt das ARRAY eine feste Anzahl von Dimensionen an. Dies bewirkt, dass die für dieses ARRAY ausgegebene DDL die exakte Anzahl von Klammern [] enthält und die Gesamtleistung des Typs optimiert. Beachten Sie, dass PG-Arrays immer implizit „nicht-dimensioniert“ sind, was bedeutet, dass sie jede Anzahl von Dimensionen speichern können, unabhängig davon, wie sie deklariert wurden.

  • zero_indexes=False – Wenn True, werden Indexwerte zwischen Python-nullbasierten und PostgreSQL-einsbasierten Indizes konvertiert, z. B. wird zu allen Indexwerten eins addiert, bevor sie an die Datenbank übergeben werden.

klasse Comparator

Definiert Vergleichsoperationen für ARRAY.

Beachten Sie, dass diese Operationen zusätzlich zu denen der Basisklasse Comparator sind, einschließlich Comparator.any() und Comparator.all().

Klassensignatur

class sqlalchemy.dialects.postgresql.ARRAY.Comparator (sqlalchemy.types.Comparator)

methode sqlalchemy.dialects.postgresql.ARRAY.Comparator.contains(other, **kwargs)

Boolescher Ausdruck. Prüft, ob Elemente eine Obermenge der Elemente des Argument-Array-Ausdrucks sind.

kwargs können von diesem Operator ignoriert werden, sind aber für die API-Konformität erforderlich.

methode sqlalchemy.dialects.postgresql.ARRAY.Comparator.contained_by(other)

Boolescher Ausdruck. Prüft, ob Elemente eine echte Teilmenge der Elemente des Argument-Array-Ausdrucks sind.

methode sqlalchemy.dialects.postgresql.ARRAY.Comparator.overlap(other)

Boolescher Ausdruck. Prüft, ob das Array gemeinsame Elemente mit einem Argument-Array-Ausdruck hat.

klasse sqlalchemy.dialects.postgresql.BIT
klasse sqlalchemy.dialects.postgresql.BYTEA

Mitglieder

__init__()

methode sqlalchemy.dialects.postgresql.BYTEA.__init__(length: int | None = None)

geerbt von der sqlalchemy.types.LargeBinary.__init__ Methode von LargeBinary

Konstruiert einen LargeBinary-Typ.

Parameter:

length – optional, eine Länge für die Spalte zur Verwendung in DDL-Anweisungen, für binäre Typen, die eine Länge akzeptieren, wie z. B. der MySQL BLOB-Typ.

klasse sqlalchemy.dialects.postgresql.CIDR

Klassensignatur

class sqlalchemy.dialects.postgresql.CIDR (sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin, sqlalchemy.types.TypeEngine)

klasse sqlalchemy.dialects.postgresql.CITEXT

Stellt den PostgreSQL CITEXT-Typ bereit.

Neu ab Version 2.0.7.

Mitglieder

__init__()

methode sqlalchemy.dialects.postgresql.CITEXT.__init__(length: int | None = None, collation: str | None = None)

geerbt von der sqlalchemy.types.String.__init__ Methode von String

Erstellt einen String-speichernden Typ.

Parameter:
  • length – optional, eine Länge für die Spalte zur Verwendung in DDL- und CAST-Ausdrücken. Kann sicher weggelassen werden, wenn kein CREATE TABLE ausgegeben wird. Bestimmte Datenbanken erfordern möglicherweise eine length für die Verwendung in DDL und lösen eine Ausnahme aus, wenn die CREATE TABLE DDL ohne Länge für VARCHAR ausgegeben wird. Ob der Wert als Bytes oder Zeichen interpretiert wird, ist datenbankspezifisch.

  • collation

    Optional, eine Spalten-Kollation zur Verwendung in DDL- und CAST-Ausdrücken. Wird mit dem COLLATE-Schlüsselwort gerendert, das von SQLite, MySQL und PostgreSQL unterstützt wird. Z.B.

    >>> from sqlalchemy import cast, select, String
    >>> print(select(cast("some string", String(collation="utf8"))))
    
    SELECT CAST(:param_1 AS VARCHAR COLLATE utf8) AS anon_1

    Hinweis

    In den meisten Fällen sollten die Datentypen Unicode oder UnicodeText für eine Column verwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.

klasse sqlalchemy.dialects.postgresql.DOMAIN

Stellt den PostgreSQL DOMAIN-Typ dar.

Ein Domain ist im Wesentlichen ein Datentyp mit optionalen Einschränkungen, die die zulässige Menge von Werten einschränken. Z.B.

PositiveInt = DOMAIN("pos_int", Integer, check="VALUE > 0", not_null=True)

UsPostalCode = DOMAIN(
    "us_postal_code",
    Text,
    check="VALUE ~ '^\d{5}$' OR VALUE ~ '^\d{5}-\d{4}$'",
)

Weitere Details finden Sie in der PostgreSQL-Dokumentation.

Neu in Version 2.0.

Mitglieder

__init__(), create(), drop()

Klassensignatur

class sqlalchemy.dialects.postgresql.DOMAIN (sqlalchemy.dialects.postgresql.named_types.NamedType, sqlalchemy.types.SchemaType)

methode sqlalchemy.dialects.postgresql.DOMAIN.__init__(name: str, data_type: _TypeEngineArgument[Any], *, collation: str | None = None, default: elements.TextClause | str | None = None, constraint_name: str | None = None, not_null: bool | None = None, check: elements.TextClause | str | None = None, create_type: bool = True, **kw: Any)

Konstruiert einen DOMAIN.

Parameter:
  • name – der Name des Domains

  • data_type – Der zugrunde liegende Datentyp des Domains. Dies kann Array-Spezifizierer enthalten.

  • collation – Eine optionale Kollation für den Domain. Wenn keine Kollation angegeben ist, wird die Standardkollation des zugrunde liegenden Datentyps verwendet. Der zugrunde liegende Typ muss kollationsfähig sein, wenn collation angegeben ist.

  • default – Die Klausel DEFAULT gibt einen Standardwert für Spalten des Domain-Datentyps an. Der Standardwert sollte ein String oder ein text()-Wert sein. Wenn kein Standardwert angegeben ist, ist der Standardwert der Nullwert.

  • constraint_name – Ein optionaler Name für eine Einschränkung. Wenn nicht angegeben, generiert das Backend einen Namen.

  • not_null – Werte dieses Domains dürfen nicht null sein. Standardmäßig sind Domains nullwertig. Wenn nicht angegeben, wird keine NULL-Klausel ausgegeben.

  • check – Die Klausel CHECK gibt eine Integritätsbeschränkung oder einen Test an, den die Werte des Domains erfüllen müssen. Eine Einschränkung muss ein Ausdruck sein, der ein boolesches Ergebnis liefert und das Schlüsselwort VALUE verwenden kann, um sich auf den getesteten Wert zu beziehen. Im Gegensatz zu PostgreSQL ist in SQLAlchemy derzeit nur eine einzige CHECK-Klausel zulässig.

  • schema – optionaler Schemaname

  • metadata – optionales MetaData-Objekt, mit dem dieser DOMAIN direkt verknüpft wird.

  • create_type – Standardmäßig True. Zeigt an, dass nach optionaler Prüfung auf die Existenz des Typs CREATE TYPE ausgegeben werden soll, wenn die übergeordnete Tabelle erstellt wird; und zusätzlich, dass DROP TYPE aufgerufen wird, wenn die Tabelle gelöscht wird.

methode sqlalchemy.dialects.postgresql.DOMAIN.create(bind, checkfirst=True, **kw)

geerbt von der NamedType.create() Methode von NamedType

Gibt CREATE DDL für diesen Typ aus.

Parameter:
  • bind – ein verbindbares Engine, Connection oder ähnliches Objekt zur Ausgabe von SQL.

  • checkfirst – wenn True, wird zunächst eine Abfrage gegen den PG-Katalog durchgeführt, um zu prüfen, ob der Typ noch nicht existiert, bevor er erstellt wird.

methode sqlalchemy.dialects.postgresql.DOMAIN.drop(bind, checkfirst=True, **kw)

geerbt von der NamedType.drop() Methode von NamedType

Gibt DROP DDL für diesen Typ aus.

Parameter:
  • bind – ein verbindbares Engine, Connection oder ähnliches Objekt zur Ausgabe von SQL.

  • checkfirst – wenn True, wird zunächst eine Abfrage gegen den PG-Katalog durchgeführt, um zu prüfen, ob der Typ tatsächlich existiert, bevor er gelöscht wird.

klasse sqlalchemy.dialects.postgresql.DOUBLE_PRECISION

Der SQL-Datentyp DOUBLE PRECISION.

Neu in Version 2.0.

Siehe auch

Double - Dokumentation für den Basistyp.

Klassensignatur

class sqlalchemy.dialects.postgresql.DOUBLE_PRECISION (sqlalchemy.types.Double)

methode sqlalchemy.dialects.postgresql.DOUBLE_PRECISION.__init__(precision: int | None = None, asdecimal: bool = False, decimal_return_scale: int | None = None)

geerbt von der sqlalchemy.types.Float.__init__ Methode von Float

Konstruiert einen Float.

Parameter:
  • precision

    die numerische Genauigkeit für die Verwendung in CREATE TABLE DDL. Backends **sollten** versuchen, diese Genauigkeit anzugeben, um eine Anzahl von Ziffern für den generischen Float-Datentyp anzuzeigen.

    Hinweis

    Für das Oracle Database-Backend wird der Parameter Float.precision bei der Ausgabe von DDL nicht akzeptiert, da Oracle Database keine Fließkomma-Genauigkeit, die als Anzahl von Dezimalstellen angegeben ist, unterstützt. Verwenden Sie stattdessen den Oracle Database-spezifischen FLOAT-Datentyp und geben Sie den Parameter FLOAT.binary_precision an. Dies ist neu in Version 2.0 von SQLAlchemy.

    Um einen datenbankunabhängigen Float zu erstellen, der separat die Binärgenauigkeit für Oracle Database angibt, verwenden Sie TypeEngine.with_variant() wie folgt:

    from sqlalchemy import Column
    from sqlalchemy import Float
    from sqlalchemy.dialects import oracle
    
    Column(
        "float_data",
        Float(5).with_variant(oracle.FLOAT(binary_precision=16), "oracle"),
    )

  • asdecimal – das gleiche Flag wie bei Numeric, aber mit dem Standardwert False. Beachten Sie, dass das Setzen dieses Flags auf True zu einer Fließkommakonvertierung führt.

  • decimal_return_scale – Der Standardmaßstab, der bei der Konvertierung von Fließkommazahlen in Python-Dezimalzahlen verwendet wird. Fließkommawerte werden aufgrund von Dezimalungenauigkeiten typischerweise viel länger sein, und die meisten Fließkommadatentypen haben keine Vorstellung von „Maßstab“, daher sucht der Fließkommatyp standardmäßig nach den ersten zehn Dezimalstellen bei der Konvertierung. Die Angabe dieses Wertes überschreibt diese Länge. Beachten Sie, dass die MySQL-Fließkommatypen, die den „Maßstab“ enthalten, den „Maßstab“ als Standard für decimal_return_scale verwenden, sofern nicht anders angegeben.

class sqlalchemy.dialects.postgresql.ENUM

PostgreSQL ENUM-Typ.

Dies ist eine Unterklasse von Enum, die Unterstützung für PG's CREATE TYPE und DROP TYPE beinhaltet.

Wenn der eingebaute Typ Enum verwendet wird und das Flag Enum.native_enum auf seinem Standardwert True belassen wird, verwendet das PostgreSQL-Backend einen ENUM-Typ als Implementierung, sodass die speziellen CREATE/DROP-Regeln verwendet werden.

Das CREATE/DROP-Verhalten von ENUM ist zwangsläufig kompliziert, aufgrund der umständlichen Beziehung, die der ENUM-Typ in Bezug auf die übergeordnete Tabelle hat, da er nur von einer einzigen Tabelle „besessen“ werden kann oder unter vielen Tabellen geteilt werden kann.

Beim Verwenden von Enum oder ENUM auf „Inline“-Weise werden CREATE TYPE und DROP TYPE entsprechend den Aufrufen der Methoden Table.create() und Table.drop() ausgegeben.

table = Table(
    "sometable",
    metadata,
    Column("some_enum", ENUM("a", "b", "c", name="myenum")),
)

table.create(engine)  # will emit CREATE ENUM and CREATE TABLE
table.drop(engine)  # will emit DROP TABLE and DROP ENUM

Um einen gemeinsamen enumerierten Typ zwischen mehreren Tabellen zu verwenden, ist es am besten, den Enum oder ENUM unabhängig zu deklarieren und ihn dem MetaData-Objekt selbst zuzuordnen.

my_enum = ENUM("a", "b", "c", name="myenum", metadata=metadata)

t1 = Table("sometable_one", metadata, Column("some_enum", myenum))

t2 = Table("sometable_two", metadata, Column("some_enum", myenum))

Wenn dieses Muster verwendet wird, muss bei der Erstellung einzelner Tabellen dennoch Vorsicht geboten sein. Die Ausgabe von CREATE TABLE ohne die Angabe von checkfirst=True verursacht weiterhin Probleme.

t1.create(engine)  # will fail: no such type 'myenum'

Wenn wir checkfirst=True angeben, prüft die Tabellenerstellung auf individueller Ebene zuerst, ob der ENUM existiert, und erstellt ihn, falls er nicht existiert.

# will check if enum exists, and emit CREATE TYPE if not
t1.create(engine, checkfirst=True)

Wenn ein ENUM-Typ auf Metadaten-Ebene verwendet wird, wird der Typ immer erstellt und gelöscht, wenn entweder die Metadaten-weite Erstellung/Löschung aufgerufen wird.

metadata.create_all(engine)  # will emit CREATE TYPE
metadata.drop_all(engine)  # will emit DROP TYPE

Der Typ kann auch direkt erstellt und gelöscht werden.

my_enum.create(engine)
my_enum.drop(engine)

Mitglieder

__init__(), create(), drop()

Klassensignatur

class sqlalchemy.dialects.postgresql.ENUM (sqlalchemy.dialects.postgresql.named_types.NamedType, sqlalchemy.types.NativeForEmulated, sqlalchemy.types.Enum)

method sqlalchemy.dialects.postgresql.ENUM.__init__(*enums, name: str | _NoArg | None = _NoArg.NO_ARG, create_type: bool = True, **kw)

Erzeugt eine ENUM.

Die Argumente sind die gleichen wie bei Enum, aber mit den folgenden zusätzlichen Parametern.

Parameter:

create_type – Standardmäßig True. Gibt an, dass CREATE TYPE ausgegeben werden soll, nachdem optional geprüft wurde, ob der Typ vorhanden ist, wenn die übergeordnete Tabelle erstellt wird; und zusätzlich, dass DROP TYPE aufgerufen wird, wenn die Tabelle gelöscht wird. Wenn False, wird keine Prüfung durchgeführt und kein CREATE TYPE oder DROP TYPE ausgegeben, es sei denn, ENUM.create() oder ENUM.drop() direkt aufgerufen werden. Das Setzen auf False ist hilfreich, wenn ein Erstellungsschema in eine SQL-Datei ohne Zugriff auf die tatsächliche Datenbank aufgerufen wird – die Methoden ENUM.create() und ENUM.drop() können verwendet werden, um SQL an ein Ziel-Bind zu senden.

method sqlalchemy.dialects.postgresql.ENUM.create(bind=None, checkfirst=True)

Gibt CREATE TYPE für diese ENUM aus.

Wenn das zugrundeliegende Dialekt PostgreSQL CREATE TYPE nicht unterstützt, wird keine Aktion ausgeführt.

Parameter:
  • bind – ein verbindbares Engine, Connection oder ein ähnliches Objekt zur Ausgabe von SQL.

  • checkfirst – wenn True, wird zuerst eine Abfrage des PG-Katalogs durchgeführt, um zu prüfen, ob der Typ bereits existiert, bevor er erstellt wird.

method sqlalchemy.dialects.postgresql.ENUM.drop(bind=None, checkfirst=True)

Gibt DROP TYPE für diese ENUM aus.

Wenn das zugrundeliegende Dialekt PostgreSQL DROP TYPE nicht unterstützt, wird keine Aktion ausgeführt.

Parameter:
  • bind – ein verbindbares Engine, Connection oder ein ähnliches Objekt zur Ausgabe von SQL.

  • checkfirst – wenn True, wird zuerst eine Abfrage des PG-Katalogs durchgeführt, um zu prüfen, ob der Typ tatsächlich existiert, bevor er gelöscht wird.

class sqlalchemy.dialects.postgresql.HSTORE

Stellt den PostgreSQL HSTORE-Typ dar.

Der HSTORE-Typ speichert Wörterbücher, die Strings enthalten, z. B.

data_table = Table(
    "data_table",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", HSTORE),
)

with engine.connect() as conn:
    conn.execute(
        data_table.insert(), data={"key1": "value1", "key2": "value2"}
    )

HSTORE bietet eine breite Palette von Operationen, einschließlich

  • Indexoperationen

    data_table.c.data["some key"] == "some value"
  • Containment-Operationen

    data_table.c.data.has_key("some key")
    
    data_table.c.data.has_all(["one", "two", "three"])
  • Verkettung

    data_table.c.data + {"k1": "v1"}

Eine vollständige Liste der speziellen Methoden finden Sie unter comparator_factory.

Änderungen in HSTORE-Spalten beim Verwenden des ORM erkennen

Für die Verwendung mit dem SQLAlchemy ORM kann es wünschenswert sein, die Verwendung von HSTORE mit MutableDict zu kombinieren, einem Wörterbuch, das jetzt Teil der sqlalchemy.ext.mutable-Erweiterung ist. Diese Erweiterung ermöglicht „In-Place“-Änderungen am Wörterbuch, z. B. das Hinzufügen neuer Schlüssel oder das Ersetzen/Entfernen bestehender Schlüssel aus dem aktuellen Wörterbuch, um Ereignisse auszulösen, die von der Unit of Work erkannt werden.

from sqlalchemy.ext.mutable import MutableDict


class MyClass(Base):
    __tablename__ = "data_table"

    id = Column(Integer, primary_key=True)
    data = Column(MutableDict.as_mutable(HSTORE))


my_object = session.query(MyClass).one()

# in-place mutation, requires Mutable extension
# in order for the ORM to detect
my_object.data["some_key"] = "some value"

session.commit()

Wenn die Erweiterung sqlalchemy.ext.mutable nicht verwendet wird, wird das ORM nicht über Änderungen am Inhalt eines vorhandenen Wörterbuchs informiert, es sei denn, dieser Wörterbuchwert wird erneut dem HSTORE-Attribut selbst zugewiesen, wodurch ein Änderungsereignis ausgelöst wird.

Siehe auch

hstore - rendert die PostgreSQL hstore() Funktion.

class Comparator

Definiert Vergleichsoperationen für HSTORE.

Klassensignatur

class sqlalchemy.dialects.postgresql.HSTORE.Comparator (sqlalchemy.types.Comparator, sqlalchemy.types.Comparator)

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.array()

Text-Array-Ausdruck. Gibt ein Array von abwechselnden Schlüsseln und Werten zurück.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.contained_by(other)

Boolescher Ausdruck. Prüft, ob die Schlüssel eine echte Teilmenge der Schlüssel des JSONB-Ausdrucks des Arguments sind.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.contains(other, **kwargs)

Boolescher Ausdruck. Prüft, ob die Schlüssel (oder das Array) eine Obermenge/eine Teilmenge der Schlüssel des JSONB-Ausdrucks des Arguments sind.

kwargs können von diesem Operator ignoriert werden, sind aber für die API-Konformität erforderlich.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.defined(key)

Boolescher Ausdruck. Prüft auf die Anwesenheit eines Nicht-NULL-Werts für den Schlüssel. Beachten Sie, dass der Schlüssel ein SQLA-Ausdruck sein kann.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.delete(key)

HStore-Ausdruck. Gibt den Inhalt dieses HStores mit dem angegebenen Schlüssel gelöscht zurück. Beachten Sie, dass der Schlüssel ein SQLA-Ausdruck sein kann.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.has_all(other)

Boolescher Ausdruck. Prüft auf die Anwesenheit aller Schlüssel in jsonb.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.has_any(other)

Boolescher Ausdruck. Prüft auf die Anwesenheit eines beliebigen Schlüssels in jsonb.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.has_key(other)

Boolescher Ausdruck. Prüft auf die Anwesenheit eines Schlüssels. Beachten Sie, dass der Schlüssel ein SQLA-Ausdruck sein kann.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.keys()

Text-Array-Ausdruck. Gibt ein Array von Schlüsseln zurück.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.matrix()

Text-Array-Ausdruck. Gibt ein Array von [Schlüssel, Wert]-Paaren zurück.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.slice(array)

HStore-Ausdruck. Gibt eine Teilmenge eines HStores zurück, die durch ein Array von Schlüsseln definiert ist.

method sqlalchemy.dialects.postgresql.HSTORE.Comparator.vals()

Text-Array-Ausdruck. Gibt ein Array von Werten zurück.

method sqlalchemy.dialects.postgresql.HSTORE.__init__(text_type=None)

Erzeugt eine neue HSTORE.

Parameter:

text_type – Der Typ, der für indizierte Werte verwendet werden soll. Standardmäßig Text.

method sqlalchemy.dialects.postgresql.HSTORE.bind_processor(dialect)

Gibt eine Konvertierungsfunktion zur Verarbeitung von Bindungswerten zurück.

Gibt eine aufrufbare Funktion zurück, die einen Bindungsparameterwert als einziges Positionsargument empfängt und einen Wert zurückgibt, der an die DB-API gesendet werden soll.

Wenn keine Verarbeitung erforderlich ist, sollte die Methode None zurückgeben.

Hinweis

Diese Methode wird nur in Bezug auf ein **dialektspezifisches Typobjekt** aufgerufen, das oft **intern für ein verwendetes Dialekt** ist und nicht dasselbe Typobjekt wie das öffentlich sichtbare ist. Daher ist es nicht möglich, eine TypeEngine-Klasse zu unterklassen, um eine alternative TypeEngine.bind_processor()-Methode bereitzustellen, es sei denn, die UserDefinedType-Klasse wird explizit unterklasset.

Um ein alternatives Verhalten für TypeEngine.bind_processor() bereitzustellen, implementieren Sie eine TypeDecorator-Klasse und stellen Sie eine Implementierung von TypeDecorator.process_bind_param() bereit.

Parameter:

dialect – Die verwendete Dialektinstanz.

attribute sqlalchemy.dialects.postgresql.HSTORE.comparator_factory

Alias von Comparator

attribute sqlalchemy.dialects.postgresql.HSTORE.hashable = False

Flag, wenn False, bedeutet, dass Werte dieses Typs nicht hashbar sind.

Wird vom ORM beim Eindeutigen machen von Ergebnislisten verwendet.

method sqlalchemy.dialects.postgresql.HSTORE.result_processor(dialect, coltype)

Gibt eine Konvertierungsfunktion zur Verarbeitung von Ergebniszeilenwerten zurück.

Gibt eine aufrufbare Funktion zurück, die einen Ergebniszeilen-Spaltenwert als einziges Positionsargument empfängt und einen Wert zurückgibt, der dem Benutzer zurückgegeben werden soll.

Wenn keine Verarbeitung erforderlich ist, sollte die Methode None zurückgeben.

Hinweis

Diese Methode wird nur in Bezug auf ein **dialektspezifisches Typobjekt** aufgerufen, das oft **intern für ein verwendetes Dialekt** ist und nicht dasselbe Typobjekt wie das öffentlich sichtbare ist. Daher ist es nicht möglich, eine TypeEngine-Klasse zu unterklassen, um eine alternative TypeEngine.result_processor()-Methode bereitzustellen, es sei denn, die UserDefinedType-Klasse wird explizit unterklasset.

Um ein alternatives Verhalten für TypeEngine.result_processor() bereitzustellen, implementieren Sie eine TypeDecorator Klasse und stellen Sie eine Implementierung von TypeDecorator.process_result_value() bereit.

Parameter:
  • dialect – Instanz des verwendeten Dialekts.

  • coltype – DBAPI coltype-Argument, das in cursor.description empfangen wird.

class sqlalchemy.dialects.postgresql.INET

Klassensignatur

class sqlalchemy.dialects.postgresql.INET (sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin, sqlalchemy.types.TypeEngine)

class sqlalchemy.dialects.postgresql.INTERVAL

PostgreSQL INTERVAL-Typ.

Mitglieder

__init__()

Klassensignatur

class sqlalchemy.dialects.postgresql.INTERVAL (sqlalchemy.types.NativeForEmulated, sqlalchemy.types._AbstractInterval)

method sqlalchemy.dialects.postgresql.INTERVAL.__init__(precision: int | None = None, fields: str | None = None) None

Konstruiere ein INTERVAL.

Parameter:
  • precision – optionale Ganzzahl-Präzisionswert

  • fields

    String-Feldspezifizierer. Ermöglicht die Begrenzung der Speicherung von Feldern, wie z. B. "YEAR", "MONTH", "DAY TO HOUR" usw.

    Neu seit Version 1.2.

class sqlalchemy.dialects.postgresql.JSON

Stellt den PostgreSQL JSON-Typ dar.

JSON wird automatisch verwendet, wenn der Basisdatentyp JSON gegen ein PostgreSQL-Backend verwendet wird. Der Basisdatentyp JSON bietet jedoch keine Python-Accessor für PostgreSQL-spezifische Vergleichsmethoden wie Comparator.astext(); zusätzlich müssen für die Verwendung von PostgreSQL JSONB explizit der Datentyp JSONB verwendet werden.

Siehe auch

JSON - Hauptdokumentation für den generischen plattformübergreifenden JSON-Datentyp.

Die vom PostgreSQL-Version von JSON bereitgestellten Operatoren umfassen

  • Indexoperationen (der Operator ->)

    data_table.c.data["some key"]
    
    data_table.c.data[5]
  • Indexoperationen, die Text zurückgeben (der Operator ->>)

    data_table.c.data["some key"].astext == "some value"

    Beachten Sie, dass eine äquivalente Funktionalität über den Accessor Comparator.as_string verfügbar ist.

  • Indexoperationen mit CAST (entspricht CAST(col ->> ['some key'] AS <type>))

    data_table.c.data["some key"].astext.cast(Integer) == 5

    Beachten Sie, dass äquivalente Funktionalität über Comparator.as_integer und ähnliche Accessoren verfügbar ist.

  • Pfadindexoperationen (der Operator #>)

    data_table.c.data[("key_1", "key_2", 5, ..., "key_n")]
  • Pfadindexoperationen, die Text zurückgeben (der Operator #>>)

    data_table.c.data[
        ("key_1", "key_2", 5, ..., "key_n")
    ].astext == "some value"

Indexoperationen geben standardmäßig ein Ausdrucksobjekt zurück, dessen Typ JSON ist, sodass weitere JSON-orientierte Anweisungen auf den Ergebnistyp angewendet werden können.

Benutzerdefinierte Serialisierer und Deserialisierer werden auf Dialektebene angegeben, d. h. über create_engine(). Der Grund dafür ist, dass bei Verwendung von psycopg2 der DBAPI nur Serialisierer auf der Ebene pro Cursor oder pro Verbindung zulässt. Z. B.

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@localhost/test",
    json_serializer=my_serialize_fn,
    json_deserializer=my_deserialize_fn,
)

Bei Verwendung des psycopg2-Dialekts wird der json_deserializer über psycopg2.extras.register_default_json an die Datenbank registriert.

Siehe auch

JSON - JSON-Typ auf Core-Ebene

JSONB

class Comparator

Definiert Vergleichsoperationen für JSON.

Klassensignatur

class sqlalchemy.dialects.postgresql.JSON.Comparator (sqlalchemy.types.Comparator)

attribute sqlalchemy.dialects.postgresql.JSON.Comparator.astext

Bei einem indizierten Ausdruck wird die "astext"-Konvertierung (z. B. "->>") verwendet, wenn sie in SQL gerendert wird.

Z. B.

select(data_table.c.data["some key"].astext)
method sqlalchemy.dialects.postgresql.JSON.__init__(none_as_null: bool = False, astext_type: TypeEngine[str] | None = None)

Erstellt einen JSON-Typ.

Parameter:
  • none_as_null

    Wenn True, wird der Wert None als SQL NULL-Wert gespeichert, nicht als JSON-Kodierung von null. Beachten Sie, dass, wenn dieses Flag False ist, der Konstrukt null() immer noch verwendet werden kann, um einen NULL-Wert zu speichern.

    from sqlalchemy import null
    
    conn.execute(table.insert(), {"data": null()})

    Siehe auch

    JSON.NULL

  • astext_type – der zu verwendende Typ für den Comparator.astext-Accessor auf indizierten Attributen. Standard ist Text.

attribute sqlalchemy.dialects.postgresql.JSON.comparator_factory

Alias für Comparator

attribute sqlalchemy.dialects.postgresql.JSON.render_bind_cast = True

Bind-Casts für den Modus BindTyping.RENDER_CASTS rendern.

Wenn True, signalisiert dieser Typ (normalerweise ein Dialekt-Impl-Typ) dem Compiler, dass ein Cast um einen gebundenen Parameter für diesen Typ gerendert werden soll.

Neu in Version 2.0.

Siehe auch

BindTyping

class sqlalchemy.dialects.postgresql.JSONB

Stellt den PostgreSQL JSONB-Typ dar.

Der JSONB-Typ speichert beliebige JSONB-Formatdaten, z. B.

data_table = Table(
    "data_table",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("data", JSONB),
)

with engine.connect() as conn:
    conn.execute(
        data_table.insert(), data={"key1": "value1", "key2": "value2"}
    )

Der JSONB-Typ umfasst alle vom JSON-Typ bereitgestellten Operationen, einschließlich der gleichen Verhaltensweisen für Indexoperationen. Er fügt auch zusätzliche Operatoren hinzu, die spezifisch für JSONB sind, darunter Comparator.has_key(), Comparator.has_all(), Comparator.has_any(), Comparator.contains(), Comparator.contained_by(), Comparator.delete_path(), Comparator.path_exists() und Comparator.path_match().

Wie der JSON-Typ erkennt auch der JSONB-Typ keine In-Place-Änderungen bei der Verwendung mit dem ORM, es sei denn, die Erweiterung sqlalchemy.ext.mutable wird verwendet.

Benutzerdefinierte Serialisierer und Deserialisierer werden mit dem JSON-Typ geteilt, indem die Schlüsselwörter json_serializer und json_deserializer verwendet werden. Diese müssen auf Dialektebene mit create_engine() angegeben werden. Bei Verwendung von psycopg2 werden die Serialisierer über psycopg2.extras.register_default_jsonb auf Verbindungsebene mit dem jsonb-Typ verknüpft, so wie psycopg2.extras.register_default_json zum Registrieren dieser Handler mit dem json-Typ verwendet wird.

Siehe auch

JSON

class Comparator

Definiert Vergleichsoperationen für JSON.

Klassensignatur

class sqlalchemy.dialects.postgresql.JSONB.Comparator (sqlalchemy.dialects.postgresql.json.Comparator)

method sqlalchemy.dialects.postgresql.JSONB.Comparator.contained_by(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Prüft, ob Schlüssel eine echte Teilmenge der Schlüssel des Argument-JSONB-Ausdrucks sind (entspricht dem Operator <@).

method sqlalchemy.dialects.postgresql.JSONB.Comparator.contains(other: Any, **kwargs: Any) ColumnElement[bool]

Boolescher Ausdruck. Prüft, ob Schlüssel (oder Array) eine Obermenge/enthalten sind von den Schlüsseln des Argument-JSONB-Ausdrucks (entspricht dem Operator @>).

kwargs können von diesem Operator ignoriert werden, sind aber für die API-Konformität erforderlich.

method sqlalchemy.dialects.postgresql.JSONB.Comparator.delete_path(array: List[str] | _pg_array[str]) ColumnElement[JSONB]

JSONB-Ausdruck. Löscht das Feld oder das Array-Element, das im Argument-Array angegeben ist (entspricht dem Operator #-).

Die Eingabe kann eine Liste von Zeichenfolgen sein, die in ein ARRAY oder eine Instanz von _postgres.array() konvertiert werden.

Neu in Version 2.0.

method sqlalchemy.dialects.postgresql.JSONB.Comparator.has_all(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Prüft auf das Vorhandensein aller Schlüssel in jsonb (entspricht dem Operator ?&)

method sqlalchemy.dialects.postgresql.JSONB.Comparator.has_any(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Prüft auf das Vorhandensein eines Schlüssels in jsonb (entspricht dem Operator ?|)

method sqlalchemy.dialects.postgresql.JSONB.Comparator.has_key(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Prüft auf das Vorhandensein eines Schlüssels (entspricht dem Operator ?). Beachten Sie, dass der Schlüssel ein SQLA-Ausdruck sein kann.

method sqlalchemy.dialects.postgresql.JSONB.Comparator.path_exists(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Prüft auf das Vorhandensein eines Elements, das durch den Argument-JSONPath-Ausdruck gegeben ist (entspricht dem Operator @?).

Neu in Version 2.0.

method sqlalchemy.dialects.postgresql.JSONB.Comparator.path_match(other: Any) ColumnElement[bool]

Boolescher Ausdruck. Prüft, ob der durch den Argument-JSONPath-Ausdruck gegebene JSONPath-Prädikat übereinstimmt (entspricht dem Operator @@).

Nur das erste Element des Ergebnisses wird berücksichtigt.

Neu in Version 2.0.

attribute sqlalchemy.dialects.postgresql.JSONB.comparator_factory

Alias für Comparator

class sqlalchemy.dialects.postgresql.JSONPATH

JSON-Pfad-Typ.

Dies ist in der Regel erforderlich, um Literalwerte in einen JSON-Pfad zu konvertieren, wenn JSON-Suchfunktionen wie jsonb_path_query_array oder jsonb_path_exists verwendet werden.

stmt = sa.select(
    sa.func.jsonb_path_query_array(
        table.c.jsonb_col, cast("$.address.id", JSONPATH)
    )
)

Klassensignatur

class sqlalchemy.dialects.postgresql.JSONPATH (sqlalchemy.dialects.postgresql.json.JSONPathType)

class sqlalchemy.dialects.postgresql.MACADDR

Klassensignatur

class sqlalchemy.dialects.postgresql.MACADDR (sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin, sqlalchemy.types.TypeEngine)

class sqlalchemy.dialects.postgresql.MACADDR8

Klassensignatur

class sqlalchemy.dialects.postgresql.MACADDR8 (sqlalchemy.dialects.postgresql.types._NetworkAddressTypeMixin, sqlalchemy.types.TypeEngine)

class sqlalchemy.dialects.postgresql.MONEY

Stellt den PostgreSQL MONEY-Typ bereit.

Je nach Treiber können Ergebniszeilen mit diesem Typ einen String-Wert zurückgeben, der Währungssymbole enthält.

Aus diesem Grund kann es ratsam sein, die Konvertierung in einen numerisch basierten Währungstyp mithilfe von TypeDecorator bereitzustellen.

import re
import decimal
from sqlalchemy import Dialect
from sqlalchemy import TypeDecorator


class NumericMoney(TypeDecorator):
    impl = MONEY

    def process_result_value(self, value: Any, dialect: Dialect) -> None:
        if value is not None:
            # adjust this for the currency and numeric
            m = re.match(r"\$([\d.]+)", value)
            if m:
                value = decimal.Decimal(m.group(1))
        return value

Alternativ kann die Konvertierung als CAST unter Verwendung der Methode TypeDecorator.column_expression() wie folgt angewendet werden:

import decimal
from sqlalchemy import cast
from sqlalchemy import TypeDecorator


class NumericMoney(TypeDecorator):
    impl = MONEY

    def column_expression(self, column: Any):
        return cast(column, Numeric())

Neu seit Version 1.2.

class sqlalchemy.dialects.postgresql.OID

Stellt den PostgreSQL OID-Typ bereit.

class sqlalchemy.dialects.postgresql.REAL

Der SQL REAL-Typ.

Siehe auch

Float - Dokumentation für den Basistyp.

Klassensignatur

class sqlalchemy.dialects.postgresql.REAL (sqlalchemy.types.Float)

method sqlalchemy.dialects.postgresql.REAL.__init__(precision: int | None = None, asdecimal: bool = False, decimal_return_scale: int | None = None)

geerbt von der sqlalchemy.types.Float.__init__ Methode von Float

Konstruiert einen Float.

Parameter:
  • precision

    die numerische Genauigkeit für die Verwendung in CREATE TABLE DDL. Backends **sollten** versuchen, diese Genauigkeit anzugeben, um eine Anzahl von Ziffern für den generischen Float-Datentyp anzuzeigen.

    Hinweis

    Für das Oracle Database-Backend wird der Parameter Float.precision bei der Ausgabe von DDL nicht akzeptiert, da Oracle Database keine Fließkomma-Genauigkeit, die als Anzahl von Dezimalstellen angegeben ist, unterstützt. Verwenden Sie stattdessen den Oracle Database-spezifischen FLOAT-Datentyp und geben Sie den Parameter FLOAT.binary_precision an. Dies ist neu in Version 2.0 von SQLAlchemy.

    Um einen datenbankunabhängigen Float zu erstellen, der separat die Binärgenauigkeit für Oracle Database angibt, verwenden Sie TypeEngine.with_variant() wie folgt:

    from sqlalchemy import Column
    from sqlalchemy import Float
    from sqlalchemy.dialects import oracle
    
    Column(
        "float_data",
        Float(5).with_variant(oracle.FLOAT(binary_precision=16), "oracle"),
    )

  • asdecimal – das gleiche Flag wie bei Numeric, aber mit dem Standardwert False. Beachten Sie, dass das Setzen dieses Flags auf True zu einer Gleitkommakonvertierung führt.

  • decimal_return_scale – Skalierung für die Konvertierung von Gleitkommazahlen in Python-Dezimalzahlen. Gleitkommazahlen sind aufgrund von Dezimalungenauigkeiten typischerweise sehr lang, und die meisten Gleitkommadatentypen haben keinen Begriff von „Skalierung“. Standardmäßig sucht der Gleitkommatyp daher nach den ersten zehn Dezimalstellen. Die Angabe dieses Werts überschreibt diese Länge. Beachten Sie, dass MySQL-Gleitkommatypen, die „Skalierung“ enthalten, die „Skalierung“ als Standard für `decimal_return_scale` verwenden, sofern nicht anders angegeben.

class sqlalchemy.dialects.postgresql.REGCONFIG

Stellt den PostgreSQL REGCONFIG-Typ bereit.

Neu in Version 2.0.0rc1.

class sqlalchemy.dialects.postgresql.REGCLASS

Stellt den PostgreSQL REGCLASS-Typ bereit.

Neu in Version 1.2.7.

class sqlalchemy.dialects.postgresql.TIMESTAMP

Stellt den PostgreSQL TIMESTAMP-Typ bereit.

Mitglieder

__init__()

method sqlalchemy.dialects.postgresql.TIMESTAMP.__init__(timezone: bool = False, precision: int | None = None) None

Konstruiert ein TIMESTAMP.

Parameter:
  • timezone – boolescher Wert, ob Zeitzone vorhanden ist, Standard ist False

  • precision

    optionaler ganzzahliger Präzisionswert

    Neu in Version 1.4.

class sqlalchemy.dialects.postgresql.TIME

PostgreSQL TIME-Typ.

Mitglieder

__init__()

method sqlalchemy.dialects.postgresql.TIME.__init__(timezone: bool = False, precision: int | None = None) None

Konstruiert ein TIME.

Parameter:
  • timezone – boolescher Wert, ob Zeitzone vorhanden ist, Standard ist False

  • precision

    optionaler ganzzahliger Präzisionswert

    Neu in Version 1.4.

class sqlalchemy.dialects.postgresql.TSQUERY

Stellt den PostgreSQL TSQUERY-Typ bereit.

Neu in Version 2.0.0rc1.

class sqlalchemy.dialects.postgresql.TSVECTOR

Der TSVECTOR-Typ implementiert den PostgreSQL-Textsuchtyp TSVECTOR.

Kann für Volltextabfragen natürlicher Sprachdokumente verwendet werden.

Siehe auch

Volltextsuche

class sqlalchemy.dialects.postgresql.UUID

Stellt den SQL-Datentyp UUID dar.

Dies ist die SQL-native Form des datenbankagnostischen Datentyps Uuid und ist abwärtskompatibel mit der vorherigen PostgreSQL-only-Version von UUID.

Der Datentyp UUID funktioniert nur auf Datenbanken, die einen SQL-Datentyp namens UUID haben. Er funktioniert nicht für Backends, die diesen exakt benannten Typ nicht haben, einschließlich SQL Server. Für backend-agnostische UUID-Werte mit nativer Unterstützung, einschließlich des UNIQUEIDENTIFIER-Datentyps von SQL Server, verwenden Sie den Datentyp Uuid.

Neu in Version 2.0.

Siehe auch

Uuid

Klassensignatur

class sqlalchemy.dialects.postgresql.UUID (sqlalchemy.types.Uuid, sqlalchemy.types.NativeForEmulated)

method sqlalchemy.dialects.postgresql.UUID.__init__(as_uuid: bool = True)

Konstruiert einen UUID-Typ.

Parameter:

as_uuid=True

wenn True, werden Werte als Python-UUID-Objekte interpretiert und über DBAPI in Zeichenketten konvertiert.

class sqlalchemy.dialects.postgresql.INT4RANGE

Stellt den PostgreSQL INT4RANGE-Typ dar.

class sqlalchemy.dialects.postgresql.INT8RANGE

Stellt den PostgreSQL INT8RANGE-Typ dar.

class sqlalchemy.dialects.postgresql.NUMRANGE

Stellt den PostgreSQL NUMRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.DATERANGE

Stellt den PostgreSQL DATERANGE-Typ dar.

class sqlalchemy.dialects.postgresql.TSRANGE

Stellt den PostgreSQL TSRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.TSTZRANGE

Stellt den PostgreSQL TSTZRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.INT4MULTIRANGE

Stellt den PostgreSQL INT4MULTIRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.INT8MULTIRANGE

Stellt den PostgreSQL INT8MULTIRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.NUMMULTIRANGE

Stellt den PostgreSQL NUMMULTIRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.DATEMULTIRANGE

Stellt den PostgreSQL DATEMULTIRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.TSMULTIRANGE

Stellt den PostgreSQL TSRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.TSTZMULTIRANGE

Stellt den PostgreSQL TSTZRANGE-Typ dar.

class sqlalchemy.dialects.postgresql.MultiRange

Repräsentiert eine Multirange-Sequenz.

Diese Listen-Unterklasse ist ein Hilfsmittel, das eine automatische Typinferenz des richtigen Multi-Range-SQL-Typs basierend auf den einzelnen Range-Werten ermöglicht. Dies ist nützlich beim Arbeiten mit Literal-Multi-Ranges.

import sqlalchemy as sa
from sqlalchemy.dialects.postgresql import MultiRange, Range

value = literal(MultiRange([Range(2, 4)]))

select(tbl).where(tbl.c.value.op("@")(MultiRange([Range(-3, 7)])))

Neu in Version 2.0.26.

Klassensignatur

class sqlalchemy.dialects.postgresql.MultiRange (builtins.list, typing.Generic)

PostgreSQL SQL-Elemente und -Funktionen

Objektname Beschreibung

aggregate_order_by

Stellt einen PostgreSQL-Aggregations-ORDER BY-Ausdruck dar.

All(other, arrexpr[, operator])

Ein Synonym für die `ARRAY`-Level-Methode Comparator.all(). Siehe diese Methode für Details.

Any(other, arrexpr[, operator])

Ein Synonym für die `ARRAY`-Level-Methode Comparator.any(). Siehe diese Methode für Details.

array

Ein PostgreSQL ARRAY-Literal.

array_agg(*arg, **kw)

PostgreSQL-spezifische Form von array_agg, stellt sicher, dass der Rückgabetyp ein ARRAY und nicht einfach ein generisches ARRAY ist, es sei denn, ein expliziter type_ wird übergeben.

hstore

Konstruiert einen hstore-Wert innerhalb eines SQL-Ausdrucks mithilfe der PostgreSQL-Funktion hstore().

phraseto_tsquery

Die PostgreSQL-SQL-Funktion phraseto_tsquery.

plainto_tsquery

Die PostgreSQL-SQL-Funktion plainto_tsquery.

to_tsquery

Die PostgreSQL-SQL-Funktion to_tsquery.

to_tsvector

Die PostgreSQL-SQL-Funktion to_tsvector.

ts_headline

Die PostgreSQL-SQL-Funktion ts_headline.

websearch_to_tsquery

Die PostgreSQL-SQL-Funktion websearch_to_tsquery.

class sqlalchemy.dialects.postgresql.aggregate_order_by

Stellt einen PostgreSQL-Aggregations-ORDER BY-Ausdruck dar.

Z. B.

from sqlalchemy.dialects.postgresql import aggregate_order_by

expr = func.array_agg(aggregate_order_by(table.c.a, table.c.b.desc()))
stmt = select(expr)

würde den Ausdruck darstellen

SELECT array_agg(a ORDER BY b DESC) FROM table;

Ähnlich

expr = func.string_agg(
    table.c.a, aggregate_order_by(literal_column("','"), table.c.a)
)
stmt = select(expr)

Würde darstellen

SELECT string_agg(a, ',' ORDER BY a) FROM table;

Geändert in Version 1.2.13: - das ORDER BY-Argument kann aus mehreren Termen bestehen

Siehe auch

array_agg

class sqlalchemy.dialects.postgresql.array

Ein PostgreSQL ARRAY-Literal.

Dies wird verwendet, um ARRAY-Literale in SQL-Ausdrücken zu erzeugen, z. B.

from sqlalchemy.dialects.postgresql import array
from sqlalchemy.dialects import postgresql
from sqlalchemy import select, func

stmt = select(array([1, 2]) + array([3, 4, 5]))

print(stmt.compile(dialect=postgresql.dialect()))

Erzeugt das SQL

SELECT ARRAY[%(param_1)s, %(param_2)s] ||
    ARRAY[%(param_3)s, %(param_4)s, %(param_5)s]) AS anon_1

Eine Instanz von array hat immer den Datentyp ARRAY. Der „innere“ Typ des Arrays wird aus den vorhandenen Werten abgeleitet, es sei denn, das Schlüsselwortargument type_ wird übergeben.

array(["foo", "bar"], type_=CHAR)

Mehrdimensionale Arrays werden durch Verschachtelung von array-Konstrukten erzeugt. Die Dimensionalität des endgültigen ARRAY-Typs wird durch rekursives Hinzufügen der Dimensionen des inneren ARRAY-Typs berechnet.

stmt = select(
    array(
        [array([1, 2]), array([3, 4]), array([column("q"), column("x")])]
    )
)
print(stmt.compile(dialect=postgresql.dialect()))

Erzeugt

SELECT ARRAY[
    ARRAY[%(param_1)s, %(param_2)s],
    ARRAY[%(param_3)s, %(param_4)s],
    ARRAY[q, x]
] AS anon_1

Neu in Version 1.3.6: Unterstützung für mehrdimensionale Array-Literale hinzugefügt

Siehe auch

ARRAY

Klassensignatur

class sqlalchemy.dialects.postgresql.array (sqlalchemy.sql.expression.ExpressionClauseList)

function sqlalchemy.dialects.postgresql.array_agg(*arg, **kw)

PostgreSQL-spezifische Form von array_agg, stellt sicher, dass der Rückgabetyp ein ARRAY und nicht einfach ein generisches ARRAY ist, es sei denn, ein expliziter type_ wird übergeben.

function sqlalchemy.dialects.postgresql.Any(other, arrexpr, operator=<built-in function eq>)

Ein Synonym für die `ARRAY`-Level-Methode Comparator.any(). Siehe diese Methode für Details.

function sqlalchemy.dialects.postgresql.All(other, arrexpr, operator=<built-in function eq>)

Ein Synonym für die `ARRAY`-Level-Methode Comparator.all(). Siehe diese Methode für Details.

class sqlalchemy.dialects.postgresql.hstore

Konstruiert einen hstore-Wert innerhalb eines SQL-Ausdrucks mithilfe der PostgreSQL-Funktion hstore().

Die Funktion hstore akzeptiert ein oder zwei Argumente, wie in der PostgreSQL-Dokumentation beschrieben.

Z. B.

from sqlalchemy.dialects.postgresql import array, hstore

select(hstore("key1", "value1"))

select(
    hstore(
        array(["key1", "key2", "key3"]),
        array(["value1", "value2", "value3"]),
    )
)

Siehe auch

HSTORE - der PostgreSQL-Datentyp HSTORE.

Mitglieder

inherit_cache, type

attribute sqlalchemy.dialects.postgresql.hstore.inherit_cache: bool | None = True

Gibt an, ob diese HasCacheKey-Instanz das Cache-Schlüssel-Generierungsschema ihrer direkten Oberklasse verwenden soll.

Das Attribut hat standardmäßig den Wert None, was bedeutet, dass ein Konstrukt noch nicht berücksichtigt hat, ob es für die Teilnahme an der Caching-Mechanik geeignet ist. Dies ist funktional äquivalent zum Setzen des Wertes auf False, außer dass auch eine Warnung ausgegeben wird.

Dieses Flag kann auf True für eine bestimmte Klasse gesetzt werden, wenn die SQL, die diesem Objekt entspricht, nicht auf Basis von Attributen geändert wird, die lokal zu dieser Klasse und nicht zu ihrer Oberklasse gehören.

Siehe auch

Unterstützung für Caching für benutzerdefinierte Konstrukte aktivieren - Allgemeine Richtlinien für die Einstellung des Attributs HasCacheKey.inherit_cache für SQL-Konstrukte von Drittanbietern oder benutzerdefinierte SQL-Konstrukte.

attribute sqlalchemy.dialects.postgresql.hstore.type

alias of HSTORE

class sqlalchemy.dialects.postgresql.to_tsvector

Die PostgreSQL-SQL-Funktion to_tsvector.

Diese Funktion wendet eine automatische Umwandlung des REGCONFIG-Arguments an, um den REGCONFIG-Datentyp automatisch zu verwenden, und wendet einen Rückgabetyp von TSVECTOR an.

Unter der Annahme, dass das PostgreSQL-Dialekt importiert wurde, entweder durch Aufruf von from sqlalchemy.dialects import postgresql oder durch Erstellen einer PostgreSQL-Engine mit create_engine("postgresql..."), wird to_tsvector automatisch verwendet, wenn sqlalchemy.func.to_tsvector() aufgerufen wird. Dies stellt sicher, dass die korrekten Argument- und Rückgabetyp-Handler zur Kompilierungs- und Ausführungszeit verwendet werden.

Neu in Version 2.0.0rc1.

Klassensignatur

class sqlalchemy.dialects.postgresql.to_tsvector (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.to_tsquery

Die PostgreSQL-SQL-Funktion to_tsquery.

Diese Funktion wendet eine automatische Konvertierung des REGCONFIG-Arguments an, um den REGCONFIG-Datentyp automatisch zu verwenden und weist einen Rückgabetyp von TSQUERY zu.

Vorausgesetzt, die PostgreSQL-Dialekt wurde importiert, entweder durch Aufrufen von from sqlalchemy.dialects import postgresql, oder durch Erstellen einer PostgreSQL-Engine mit create_engine("postgresql..."), wird to_tsquery automatisch beim Aufrufen von sqlalchemy.func.to_tsquery() verwendet, wodurch sichergestellt wird, dass die korrekten Argument- und Rückgabetyp-Handler zur Kompilierungs- und Ausführungszeit verwendet werden.

Neu in Version 2.0.0rc1.

Klassensignatur

class sqlalchemy.dialects.postgresql.to_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.plainto_tsquery

Die PostgreSQL-SQL-Funktion plainto_tsquery.

Diese Funktion wendet eine automatische Konvertierung des REGCONFIG-Arguments an, um den REGCONFIG-Datentyp automatisch zu verwenden und weist einen Rückgabetyp von TSQUERY zu.

Vorausgesetzt, der PostgreSQL-Dialekt wurde importiert, entweder durch Aufrufen von from sqlalchemy.dialects import postgresql, oder durch Erstellen einer PostgreSQL-Engine mit create_engine("postgresql..."), wird plainto_tsquery automatisch beim Aufrufen von sqlalchemy.func.plainto_tsquery() verwendet, wodurch sichergestellt wird, dass die korrekten Argument- und Rückgabetyp-Handler zur Kompilierungs- und Ausführungszeit verwendet werden.

Neu in Version 2.0.0rc1.

Klassensignatur

class sqlalchemy.dialects.postgresql.plainto_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.phraseto_tsquery

Die PostgreSQL-SQL-Funktion phraseto_tsquery.

Diese Funktion wendet eine automatische Konvertierung des REGCONFIG-Arguments an, um den REGCONFIG-Datentyp automatisch zu verwenden und weist einen Rückgabetyp von TSQUERY zu.

Vorausgesetzt, der PostgreSQL-Dialekt wurde importiert, entweder durch Aufrufen von from sqlalchemy.dialects import postgresql, oder durch Erstellen einer PostgreSQL-Engine mit create_engine("postgresql..."), wird phraseto_tsquery automatisch beim Aufrufen von sqlalchemy.func.phraseto_tsquery() verwendet, wodurch sichergestellt wird, dass die korrekten Argument- und Rückgabetyp-Handler zur Kompilierungs- und Ausführungszeit verwendet werden.

Neu in Version 2.0.0rc1.

Klassensignatur

class sqlalchemy.dialects.postgresql.phraseto_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.websearch_to_tsquery

Die PostgreSQL-SQL-Funktion websearch_to_tsquery.

Diese Funktion wendet eine automatische Konvertierung des REGCONFIG-Arguments an, um den REGCONFIG-Datentyp automatisch zu verwenden und weist einen Rückgabetyp von TSQUERY zu.

Vorausgesetzt, der PostgreSQL-Dialekt wurde importiert, entweder durch Aufrufen von from sqlalchemy.dialects import postgresql, oder durch Erstellen einer PostgreSQL-Engine mit create_engine("postgresql..."), wird websearch_to_tsquery automatisch beim Aufrufen von sqlalchemy.func.websearch_to_tsquery() verwendet, wodurch sichergestellt wird, dass die korrekten Argument- und Rückgabetyp-Handler zur Kompilierungs- und Ausführungszeit verwendet werden.

Neu in Version 2.0.0rc1.

Klassensignatur

class sqlalchemy.dialects.postgresql.websearch_to_tsquery (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

class sqlalchemy.dialects.postgresql.ts_headline

Die PostgreSQL-SQL-Funktion ts_headline.

Diese Funktion wendet eine automatische Konvertierung des REGCONFIG-Arguments an, um den REGCONFIG-Datentyp automatisch zu verwenden und weist einen Rückgabetyp von TEXT zu.

Vorausgesetzt, der PostgreSQL-Dialekt wurde importiert, entweder durch Aufrufen von from sqlalchemy.dialects import postgresql, oder durch Erstellen einer PostgreSQL-Engine mit create_engine("postgresql..."), wird ts_headline automatisch beim Aufrufen von sqlalchemy.func.ts_headline() verwendet, wodurch sichergestellt wird, dass die korrekten Argument- und Rückgabetyp-Handler zur Kompilierungs- und Ausführungszeit verwendet werden.

Neu in Version 2.0.0rc1.

Klassensignatur

class sqlalchemy.dialects.postgresql.ts_headline (sqlalchemy.dialects.postgresql.ext._regconfig_fn)

PostgreSQL Constraint-Typen

SQLAlchemy unterstützt PostgreSQL EXCLUDE-Constraints über die Klasse ExcludeConstraint.

Objektname Beschreibung

ExcludeConstraint

Ein EXCLUDE-Constraint auf Tabellenebene.

class sqlalchemy.dialects.postgresql.ExcludeConstraint

Ein EXCLUDE-Constraint auf Tabellenebene.

Definiert einen EXCLUDE-Constraint, wie in der PostgreSQL-Dokumentation beschrieben.

Mitglieder

__init__()

method sqlalchemy.dialects.postgresql.ExcludeConstraint.__init__(*elements, **kw)

Erstellt ein ExcludeConstraint-Objekt.

Z. B.

const = ExcludeConstraint(
    (Column("period"), "&&"),
    (Column("group"), "="),
    where=(Column("group") != "some group"),
    ops={"group": "my_operator_class"},
)

Der Constraint wird normalerweise direkt in die Table-Konstruktion eingebettet oder später über append_constraint() hinzugefügt.

some_table = Table(
    "some_table",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("period", TSRANGE()),
    Column("group", String),
)

some_table.append_constraint(
    ExcludeConstraint(
        (some_table.c.period, "&&"),
        (some_table.c.group, "="),
        where=some_table.c.group != "some group",
        name="some_table_excl_const",
        ops={"group": "my_operator_class"},
    )
)

Der im Beispiel definierte EXCLUDE-Constraint erfordert die Erweiterung btree_gist, die mit dem Befehl CREATE EXTENSION btree_gist; erstellt werden kann.

Parameter:
  • *elements

    Eine Sequenz von zwei Tupeln der Form (column, operator), wobei „column“ entweder ein Column-Objekt, ein SQL-Ausdruckselement (z. B. func.int8range(table.from, table.to)) oder der Name einer Spalte als String ist, und „operator“ ein String ist, der den zu verwendenden Operator enthält (z. B. “&&” oder “=”).

    Um einen Spaltennamen anzugeben, wenn kein Column-Objekt verfügbar ist und gleichzeitig sichergestellt wird, dass alle notwendigen Anführungsregeln angewendet werden, sollte ein Ad-hoc Column- oder column()-Objekt verwendet werden. Die column kann auch ein String-SQL-Ausdruck sein, wenn er als literal_column() oder text() übergeben wird.

  • name – Optional, der In-Database-Name dieses Constraints.

  • deferrable – Optionaler Boolescher Wert. Wenn gesetzt, wird DEFERRABLE oder NOT DEFERRABLE ausgegeben, wenn DDL für diesen Constraint erzeugt wird.

  • initially – Optionaler String. Wenn gesetzt, wird INITIALLY <value> ausgegeben, wenn DDL für diesen Constraint erzeugt wird.

  • using – Optionaler String. Wenn gesetzt, wird USING <index_method> ausgegeben, wenn DDL für diesen Constraint erzeugt wird. Standard ist 'gist'.

  • where

    Optionaler SQL-Ausdruckskonstrukt oder literaler SQL-String. Wenn gesetzt, wird WHERE <predicate> ausgegeben, wenn DDL für diesen Constraint erzeugt wird.

    Warnung

    Das Argument ExcludeConstraint.where für ExcludeConstraint kann als Python-String-Argument übergeben werden, das als **vertrauenswürdiger SQL-Text** behandelt und unverändert gerendert wird. **ÜBERGEBEN SIE KEINE UNVERTRAULICHEN EINGABEN AN DIESEN PARAMETER**.

  • ops

    Optionales Dictionary. Wird verwendet, um Operator-Klassen für die Elemente zu definieren; funktioniert genauso wie der postgresql_ops-Parameter, der an die Index-Konstruktion übergeben wird.

    Neu in Version 1.3.21.

    Siehe auch

    Operator-Klassen - allgemeine Beschreibung, wie PostgreSQL-Operator-Klassen spezifiziert werden.

Beispiel

from sqlalchemy.dialects.postgresql import ExcludeConstraint, TSRANGE


class RoomBooking(Base):
    __tablename__ = "room_booking"

    room = Column(Integer(), primary_key=True)
    during = Column(TSRANGE())

    __table_args__ = (ExcludeConstraint(("room", "="), ("during", "&&")),)

PostgreSQL DML-Konstrukte

Objektname Beschreibung

insert(table)

Erstellt eine PostgreSQL-spezifische Variante der Insert-Konstruktion.

Insert

PostgreSQL-spezifische Implementierung von INSERT.

function sqlalchemy.dialects.postgresql.insert(table: _DMLTableArgument) Insert

Erstellt eine PostgreSQL-spezifische Variante der Insert-Konstruktion.

Die Funktion sqlalchemy.dialects.postgresql.insert() erstellt ein sqlalchemy.dialects.postgresql.Insert. Diese Klasse basiert auf der Dialekt-unabhängigen Insert-Konstruktion, die mit der Funktion insert() in SQLAlchemy Core erstellt werden kann.

Die Insert-Konstruktion enthält zusätzliche Methoden: Insert.on_conflict_do_update(), Insert.on_conflict_do_nothing().

class sqlalchemy.dialects.postgresql.Insert

PostgreSQL-spezifische Implementierung von INSERT.

Fügt Methoden für PG-spezifische Syntaxen wie ON CONFLICT hinzu.

Das Insert-Objekt wird über die Funktion sqlalchemy.dialects.postgresql.insert() erstellt.

attribute sqlalchemy.dialects.postgresql.Insert.excluded

Stellt den Namespace excluded für eine ON CONFLICT-Anweisung bereit.

Die PG-Klausel ON CONFLICT erlaubt einen Verweis auf die einzufügende Zeile, bekannt als excluded. Dieses Attribut stellt alle Spalten in dieser Zeile zur Verfügung, auf die verwiesen werden kann.

Tipp

Das Attribut Insert.excluded ist eine Instanz von ColumnCollection, die eine Schnittstelle bietet, die der der Table.c-Sammlung entspricht, wie unter Zugriff auf Tabellen und Spalten beschrieben. Mit dieser Sammlung sind normale Namen als Attribute zugänglich (z. B. stmt.excluded.some_column), aber spezielle Namen und Dictionary-Methodennamen sollten über indizierten Zugriff abgerufen werden, wie z. B. stmt.excluded["column name"] oder stmt.excluded["values"]. Weitere Beispiele finden Sie im Docstring von ColumnCollection.

Siehe auch

INSERT…ON CONFLICT (Upsert) - Beispiel für die Verwendung von Insert.excluded.

attribute sqlalchemy.dialects.postgresql.Insert.inherit_cache: bool | None = False

Gibt an, ob diese HasCacheKey-Instanz das Cache-Schlüssel-Generierungsschema ihrer direkten Oberklasse verwenden soll.

Das Attribut hat standardmäßig den Wert None, was bedeutet, dass ein Konstrukt noch nicht berücksichtigt hat, ob es für die Teilnahme an der Caching-Mechanik geeignet ist. Dies ist funktional äquivalent zum Setzen des Wertes auf False, außer dass auch eine Warnung ausgegeben wird.

Dieses Flag kann auf True für eine bestimmte Klasse gesetzt werden, wenn die SQL, die diesem Objekt entspricht, nicht auf Basis von Attributen geändert wird, die lokal zu dieser Klasse und nicht zu ihrer Oberklasse gehören.

Siehe auch

Unterstützung für Caching für benutzerdefinierte Konstrukte aktivieren - Allgemeine Richtlinien für die Einstellung des Attributs HasCacheKey.inherit_cache für SQL-Konstrukte von Drittanbietern oder benutzerdefinierte SQL-Konstrukte.

method sqlalchemy.dialects.postgresql.Insert.on_conflict_do_nothing(constraint: str | ColumnCollectionConstraint | Index | None = None, index_elements: Iterable[Column[Any] | str | DDLConstraintColumnRole] | None = None, index_where: WhereHavingRole | None = None) Self

Gibt eine DO NOTHING-Aktion für die ON CONFLICT-Klausel an.

Die Argumente constraint und index_elements sind optional, aber nur eines davon kann angegeben werden.

Parameter:
  • constraint – Der Name eines eindeutigen oder Ausschluss-Constraints für die Tabelle oder das Constraint-Objekt selbst, wenn es ein .name-Attribut hat.

  • index_elements – Eine Sequenz, die aus Spaltennamen als Strings, Column-Objekten oder anderen Spaltenausdrucksobjekten besteht, die zur Ableitung eines Zielindexes verwendet werden.

  • index_where – Zusätzliches WHERE-Kriterium, das zur Ableitung eines bedingten Zielindexes verwendet werden kann.

method sqlalchemy.dialects.postgresql.Insert.on_conflict_do_update(constraint: str | ColumnCollectionConstraint | Index | None = None, index_elements: Iterable[Column[Any] | str | DDLConstraintColumnRole] | None = None, index_where: WhereHavingRole | None = None, set_: Mapping[Any, Any] | ColumnCollection[Any, Any] | None = None, where: WhereHavingRole | None = None) Self

Gibt eine DO UPDATE SET-Aktion für die ON CONFLICT-Klausel an.

Entweder das Argument constraint oder index_elements ist erforderlich, aber nur eines davon kann angegeben werden.

Parameter:
  • constraint – Der Name eines eindeutigen oder Ausschluss-Constraints für die Tabelle oder das Constraint-Objekt selbst, wenn es ein .name-Attribut hat.

  • index_elements – Eine Sequenz, die aus Spaltennamen als Strings, Column-Objekten oder anderen Spaltenausdrucksobjekten besteht, die zur Ableitung eines Zielindexes verwendet werden.

  • index_where – Zusätzliches WHERE-Kriterium, das zur Ableitung eines bedingten Zielindexes verwendet werden kann.

  • set_

    Ein Dictionary oder ein anderes Mapping-Objekt, bei dem die Schlüssel entweder Namen von Spalten in der Zieltabelle oder Column-Objekte oder andere ORM-gemappte Spalten sind, die der Zieltabelle entsprechen, und Ausdrücke oder Literale als Werte, die die auszuführenden SET-Aktionen angeben.

    Neu in Version 1.4: Der Parameter Insert.on_conflict_do_update.set_ unterstützt Column-Objekte der Ziel-Table als Schlüssel.

    Warnung

    Dieses Dictionary berücksichtigt **keine** Python-seitig definierten Standard-UPDATE-Werte oder Generierungsfunktionen, z. B. solche, die mit Column.onupdate angegeben werden. Diese Werte werden für einen ON CONFLICT-Stil-UPDATE nicht ausgeführt, es sei denn, sie werden manuell im Dictionary Insert.on_conflict_do_update.set_ angegeben.

  • where – Optionales Argument. Ein Ausdrucksobjekt, das eine WHERE-Klausel darstellt, die die von DO UPDATE SET betroffenen Zeilen einschränkt. Zeilen, die die WHERE-Bedingung nicht erfüllen, werden nicht aktualisiert (effektiv ein DO NOTHING für diese Zeilen).

psycopg2

Unterstützung für die PostgreSQL-Datenbank über den psycopg2-Treiber.

DBAPI

Dokumentation und Download-Informationen (falls zutreffend) für psycopg2 sind verfügbar unter: https://pypi.org/project/psycopg2/

Verbindung

Verbindungszeichenfolge

postgresql+psycopg2://user:password@host:port/dbname[?key=value&key=value...]

psycopg2 Connect-Argumente

Schlüsselwortargumente, die spezifisch für den SQLAlchemy psycopg2-Dialekt sind, können an create_engine() übergeben werden und umfassen die folgenden:

Tipp

Die oben genannten Schlüsselwortargumente sind Dialekt-Schlüsselwortargumente, was bedeutet, dass sie als explizite Schlüsselwortargumente an create_engine() übergeben werden.

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@localhost/test",
    isolation_level="SERIALIZABLE",
)

Diese sollten nicht mit DBAPI-Verbindungsargumenten verwechselt werden, die als Teil des create_engine.connect_args-Wörterbuchs übergeben werden und/oder in der URL-Abfragezeichenfolge übergeben werden, wie im Abschnitt Benutzerdefinierte DBAPI connect()-Argumente / on-connect-Routinen detailliert beschrieben.

SSL-Verbindungen

Das psycopg2-Modul verfügt über ein Verbindungsargument namens sslmode zur Steuerung seines Verhaltens in Bezug auf sichere (SSL) Verbindungen. Der Standardwert ist sslmode=prefer; es wird versucht, eine SSL-Verbindung herzustellen, und wenn dies fehlschlägt, wird auf eine unverschlüsselte Verbindung zurückgegriffen. sslmode=require kann verwendet werden, um sicherzustellen, dass nur sichere Verbindungen hergestellt werden. Konsultieren Sie die psycopg2 / libpq-Dokumentation für weitere verfügbare Optionen.

Beachten Sie, dass sslmode spezifisch für psycopg2 ist, daher ist es in der Verbindungs-URI enthalten

engine = sa.create_engine(
    "postgresql+psycopg2://scott:tiger@192.168.0.199:5432/test?sslmode=require"
)

Unix-Domain-Verbindungen

psycopg2 unterstützt die Verbindung über Unix-Domain-Verbindungen. Wenn der host-Teil der URL weggelassen wird, übergibt SQLAlchemy None an psycopg2, was eine Unix-Domain-Kommunikation anstelle einer TCP/IP-Kommunikation angibt

create_engine("postgresql+psycopg2://user:password@/dbname")

Standardmäßig ist die verwendete Socket-Datei zum Verbinden mit einem Unix-Domain-Socket in /tmp oder mit dem beim Erstellen von PostgreSQL angegebenen Socket-Verzeichnis. Dieser Wert kann überschrieben werden, indem ein Pfadname an psycopg2 übergeben wird, wobei host als zusätzliches Schlüsselwortargument verwendet wird

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=/var/lib/postgresql"
)

Warnung

Das hier akzeptierte Format erlaubt neben dem "host"-Query-String-Argument auch einen Hostnamen in der Haupt-URL. Bei Verwendung dieses URL-Formats wird der anfängliche Host stillschweigend ignoriert. Das heißt, diese URL

engine = create_engine(
    "postgresql+psycopg2://user:password@myhost1/dbname?host=myhost2"
)

Oben wird der Hostname myhost1 stillschweigend ignoriert und verworfen. Der verbundene Host ist der myhost2-Host.

Dies dient der Aufrechterhaltung eines gewissen Maßes an Kompatibilität mit dem URL-Format von PostgreSQL selbst, das getestet wurde, um sich gleich zu verhalten, und für das Tools wie PifPaf zwei Hostnamen fest kodieren.

Siehe auch

PQconnectdbParams

Festlegen mehrerer Fallback-Hosts

psycopg2 unterstützt mehrere Verbindungspunkte in der Verbindungszeichenfolge. Wenn der Parameter host mehrmals im Abfrageteil der URL verwendet wird, erstellt SQLAlchemy eine einzige Zeichenfolge der bereitgestellten Host- und Portinformationen, um die Verbindungen herzustellen. Tokens können host::port oder nur host sein; in letzterem Fall wird der Standardport von libpq ausgewählt. Im folgenden Beispiel werden drei Hostverbindungen angegeben, für HostA::PortA, HostB, der sich mit dem Standardport verbindet, und HostC::PortC

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA:PortA&host=HostB&host=HostC:PortC"
)

Alternativ kann auch das libpq-Query-String-Format verwendet werden; dies gibt host und port als einzelne Query-String-Argumente mit komma-separierten Listen an - der Standardport kann durch Angabe eines leeren Werts in der kommagetrennten Liste gewählt werden

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA,HostB,HostC&port=PortA,,PortC"
)

Bei beiden URL-Stilen wird versucht, Verbindungen zu jedem Host anhand einer konfigurierbaren Strategie herzustellen, die über den libpq-Parameter target_session_attrs konfiguriert werden kann. Laut libpq ist der Standardwert any, was bedeutet, dass versucht wird, eine Verbindung zu jedem Host herzustellen, bis eine Verbindung erfolgreich ist. Andere Strategien umfassen primary, prefer-standby usw. Die vollständige Liste ist von PostgreSQL unter libpq connection strings dokumentiert.

Beispiel: Angabe zweier Hosts mit der primary-Strategie

create_engine(
    "postgresql+psycopg2://user:password@/dbname?host=HostA:PortA&host=HostB&host=HostC:PortC&target_session_attrs=primary"
)

Geändert in Version 1.4.40: Portangabe im psycopg2-Mehrfachhostformat ist repariert, zuvor wurden Ports in diesem Kontext nicht korrekt interpretiert. Das kommagetrennte Format von libpq wird ebenfalls jetzt unterstützt.

Neu in Version 1.3.20: Unterstützung für mehrere Hosts in der PostgreSQL-Verbindungszeichenfolge.

Siehe auch

libpq connection strings - siehe diesen Abschnitt in der libpq-Dokumentation für vollständige Hintergründe zur Unterstützung mehrerer Hosts.

Leere DSN-Verbindungen / Umgebungsvariablen-Verbindungen

Der psycopg2 DBAPI kann sich mit PostgreSQL verbinden, indem er eine leere DSN an die libpq-Clientbibliothek übergibt, was standardmäßig angibt, dass eine Verbindung zu einer localhost PostgreSQL-Datenbank hergestellt wird, die für "Trust"-Verbindungen geöffnet ist. Dieses Verhalten kann durch die Verwendung einer bestimmten Reihe von Umgebungsvariablen, die mit PG_... präfixiert sind, weiter angepasst werden. Diese werden von libpq verarbeitet, um jeden oder alle Elemente der Verbindungszeichenfolge zu ersetzen.

Für diese Form kann die URL ohne Elemente außer dem anfänglichen Schema übergeben werden

engine = create_engine("postgresql+psycopg2://")

In der obigen Form wird eine leere "dsn"-Zeichenfolge an die Funktion psycopg2.connect() übergeben, die wiederum eine leere DSN darstellt, die an libpq übergeben wird.

Neu in Version 1.3.2: Unterstützung für parameterlose Verbindungen mit psycopg2.

Siehe auch

Environment Variables - PostgreSQL-Dokumentation zur Verwendung von PG_...-Umgebungsvariablen für Verbindungen.

Ausführungsoptionen pro Anweisung/Verbindung

Die folgenden DBAPI-spezifischen Optionen werden berücksichtigt, wenn sie mit Connection.execution_options(), Executable.execution_options(), Query.execution_options() verwendet werden, zusätzlich zu denen, die nicht spezifisch für DBAPIs sind.

  • isolation_level - Legt das Transaktionsisolationslevel für die Lebensdauer einer Connection fest (kann nur für eine Verbindung, nicht für eine Anweisung oder Abfrage festgelegt werden). Siehe Psycopg2 Transaktionsisolationslevel.

  • stream_results - Aktiviert oder deaktiviert die Verwendung von serverseitigen Cursors von psycopg2 - diese Funktion nutzt "benannte" Cursors in Kombination mit speziellen Ergebnisverarbeitungsmethoden, sodass Ergebniszeilen nicht vollständig gepuffert werden. Standardmäßig auf False gesetzt, d.h. Cursors werden standardmäßig gepuffert.

  • max_row_buffer - Bei Verwendung von stream_results ein Ganzzahlwert, der die maximale Anzahl von Zeilen angibt, die gleichzeitig gepuffert werden sollen. Dies wird von der BufferedRowCursorResult interpretiert, und wenn es weggelassen wird, wächst der Puffer, um letztendlich 1000 Zeilen gleichzeitig zu speichern.

    Geändert in Version 1.4: Die max_row_buffer-Größe kann jetzt größer als 1000 sein, und der Puffer wächst bis zu dieser Größe.

Psycopg2 Fast Execution Helpers

Moderne Versionen von psycopg2 enthalten eine Funktion namens Fast Execution Helpers, die in Benchmarks gezeigt hat, die Leistung von psycopg2s executemany() zu verbessern, hauptsächlich bei INSERT-Anweisungen, um mindestens eine Größenordnung.

SQLAlchemy implementiert eine native Form des "insert many values"-Handlers, der eine INSERT-Anweisung mit einer Zeile umschreibt, um viele Werte gleichzeitig innerhalb einer erweiterten VALUES-Klausel aufzunehmen. Dieser Handler ist äquivalent zum execute_values()-Handler von psycopg2. Ein Überblick über diese Funktion und ihre Konfiguration finden Sie unter "Insert Many Values"-Verhalten für INSERT-Anweisungen.

Neu in Version 2.0: Der psycopg2 execute_values() Fast Execution Helper wurde durch einen nativen SQLAlchemy-Mechanismus namens insertmanyvalues ersetzt.

Der psycopg2-Dialekt behält die Fähigkeit, die psycopg2-spezifische execute_batch()-Funktion zu verwenden, obwohl nicht erwartet wird, dass dies eine weit verbreitete Funktion ist. Die Verwendung dieser Erweiterung kann durch die executemany_mode-Flagge aktiviert werden, die an create_engine() übergeben werden kann.

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@host/dbname",
    executemany_mode="values_plus_batch",
)

Mögliche Optionen für executemany_mode sind

  • values_only - Dies ist der Standardwert. Der native insertmanyvalues-Handler von SQLAlchemy wird für qualifizierende INSERT-Anweisungen verwendet, vorausgesetzt, create_engine.use_insertmanyvalues bleibt bei seinem Standardwert von True. Dieser Handler schreibt einfache INSERT-Anweisungen neu, um mehrere VALUES-Klauseln einzuschließen, sodass viele Parametersätze mit einer Anweisung eingefügt werden können.

  • 'values_plus_batch' - Der native insertmanyvalues-Handler von SQLAlchemy wird für qualifizierende INSERT-Anweisungen verwendet, vorausgesetzt, create_engine.use_insertmanyvalues bleibt bei seinem Standardwert von True. Anschließend wird der execute_batch()-Handler von psycopg2 für qualifizierende UPDATE- und DELETE-Anweisungen verwendet, wenn diese mit mehreren Parametersätzen ausgeführt werden. Bei Verwendung dieses Modus enthält das Attribut CursorResult.rowcount keinen Wert für Ausführungen im executemany-Stil gegen UPDATE- und DELETE-Anweisungen.

Geändert in Version 2.0: Die Optionen 'batch' und 'None' aus dem psycopg2 executemany_mode wurden entfernt. Die Steuerung des Batchings für INSERT-Anweisungen erfolgt nun über den Engine-Level-Parameter create_engine.use_insertmanyvalues.

Der Begriff "qualifizierende Anweisungen" bezieht sich darauf, dass die auszuführende Anweisung ein Core insert()-, update()- oder delete()-Konstrukt ist und nicht eine reine Text-SQL-Anweisung oder eine mit text() erstellte. Es kann sich auch nicht um eine spezielle "Erweiterungsanweisung" wie eine "ON CONFLICT" "Upsert"-Anweisung handeln. Bei Verwendung des ORM sind alle INSERT/UPDATE/DELETE-Anweisungen, die vom ORM-Flush-Prozess verwendet werden, qualifizierend.

Die "Seitengröße" für die psycopg2 "batch"-Strategie kann durch Verwendung des Parameters executemany_batch_page_size beeinflusst werden, der standardmäßig auf 100 gesetzt ist.

Für die "insertmanyvalues"-Funktion kann die Seitengröße über den Parameter create_engine.insertmanyvalues_page_size gesteuert werden, der standardmäßig auf 1000 gesetzt ist. Ein Beispiel für die Änderung beider Parameter ist unten aufgeführt

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@host/dbname",
    executemany_mode="values_plus_batch",
    insertmanyvalues_page_size=5000,
    executemany_batch_page_size=500,
)

Siehe auch

"Insert Many Values"-Verhalten für INSERT-Anweisungen - Hintergrund zu "insertmanyvalues"

Mehrere Parameter senden - Allgemeine Informationen zur Verwendung des Connection-Objekts zur Ausführung von Anweisungen auf eine Weise, die die DBAPI .executemany()-Methode nutzt.

Unicode mit Psycopg2

Der psycopg2 DBAPI-Treiber unterstützt Unicode-Daten transparent.

Die Client-Zeichenkodierung kann für den psycopg2-Dialekt auf folgende Weise gesteuert werden

  • Für PostgreSQL 9.1 und höher kann der client_encoding-Parameter in der Datenbank-URL übergeben werden; dieser Parameter wird von der zugrunde liegenden libpq PostgreSQL-Clientbibliothek verarbeitet.

    engine = create_engine(
        "postgresql+psycopg2://user:pass@host/dbname?client_encoding=utf8"
    )

    Alternativ kann der obige client_encoding-Wert über create_engine.connect_args für die programmatische Einrichtung mit libpq übergeben werden.

    engine = create_engine(
        "postgresql+psycopg2://user:pass@host/dbname",
        connect_args={"client_encoding": "utf8"},
    )
  • Für alle PostgreSQL-Versionen unterstützt psycopg2 einen clientseitigen Kodierungswert, der an die Datenbankverbindungen übergeben wird, wenn diese hergestellt werden. Der SQLAlchemy psycopg2-Dialekt unterstützt dies mit dem Parameter client_encoding, der an create_engine() übergeben wird.

    engine = create_engine(
        "postgresql+psycopg2://user:pass@host/dbname", client_encoding="utf8"
    )

    Tipp

    Der obige client_encoding-Parameter ist zugegebenermaßen der Verwendung des Parameters im create_engine.connect_args-Wörterbuch ähneln. Der Unterschied besteht darin, dass der Parameter von psycopg2 verarbeitet und mit SET client_encoding TO 'utf8' an die Datenbankverbindung übergeben wird; im zuvor erwähnten Stil wird der Parameter stattdessen über psycopg2 übergeben und von der libpq-Bibliothek verarbeitet.

  • Eine gängige Methode, die Client-Kodierung bei PostgreSQL-Datenbanken einzustellen, ist die Sicherstellung, dass sie in der serverseitigen Datei postgresql.conf konfiguriert ist; dies ist die empfohlene Methode, um die Kodierung für einen Server festzulegen, der in allen Datenbanken konsistent eine Kodierung hat.

    # postgresql.conf file
    
    # client_encoding = sql_ascii # actually, defaults to database
    # encoding
    client_encoding = utf8

Transaktionen

Der psycopg2-Dialekt unterstützt SAVEPOINT- und Two-Phase-Commit-Operationen vollständig.

Psycopg2 Transaktionsisolationslevel

Wie in Transaktionsisolationslevel erläutert, unterstützen alle PostgreSQL-Dialekte das Einstellen des Transaktionsisolationslevels sowohl über den Parameter isolation_level, der an create_engine() übergeben wird, als auch über das isolation_level-Argument von Connection.execution_options(). Bei Verwendung des psycopg2-Dialekts verwenden diese Optionen die set_isolation_level()-Verbindungsmethode von psycopg2, anstatt eine PostgreSQL-Direktive auszugeben; dies liegt daran, dass die API-Level-Einstellung von psycopg2 ohnehin immer zu Beginn jeder Transaktion ausgegeben wird.

Der psycopg2-Dialekt unterstützt diese Konstanten für das Isolationslevel

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • AUTOCOMMIT

NOTICE-Protokollierung

Der psycopg2-Dialekt protokolliert PostgreSQL NOTICE-Nachrichten über den Logger sqlalchemy.dialects.postgresql. Wenn dieser Logger auf das Niveau logging.INFO gesetzt ist, werden Notice-Nachrichten protokolliert.

import logging

logging.getLogger("sqlalchemy.dialects.postgresql").setLevel(logging.INFO)

Oben wird davon ausgegangen, dass die Protokollierung extern konfiguriert ist. Wenn dies nicht der Fall ist, müssen Konfigurationen wie logging.basicConfig() verwendet werden.

import logging

logging.basicConfig()  # log messages to stdout
logging.getLogger("sqlalchemy.dialects.postgresql").setLevel(logging.INFO)

Siehe auch

Logging HOWTO - auf der Website von python.org

HSTORE-Typ

Die psycopg2 DBAPI enthält eine Erweiterung zur nativen Handhabung der Marshalling des HSTORE-Typs. Der SQLAlchemy psycopg2-Dialekt aktiviert diese Erweiterung standardmäßig, wenn psycopg2 Version 2.4 oder höher verwendet wird und erkannt wird, dass die Zieldatenbank für die Verwendung des HSTORE-Typs eingerichtet ist. Mit anderen Worten, wenn der Dialekt die erste Verbindung herstellt, wird eine Sequenz wie die folgende ausgeführt:

  1. Fordern Sie die verfügbaren HSTORE-OIDs mit psycopg2.extras.HstoreAdapter.get_oids() an. Wenn diese Funktion eine Liste von HSTORE-Identifikatoren zurückgibt, stellen wir fest, dass die HSTORE-Erweiterung vorhanden ist. Diese Funktion wird übersprungen, wenn die installierte Version von psycopg2 kleiner als Version 2.4 ist.

  2. Wenn das Flag use_native_hstore auf seinem Standardwert True steht und wir festgestellt haben, dass HSTORE-OIDs verfügbar sind, wird die Erweiterung psycopg2.extensions.register_hstore() für alle Verbindungen aufgerufen.

Die Erweiterung register_hstore() hat zur Folge, dass alle Python-Wörterbücher als Parameter akzeptiert werden, unabhängig vom Typ der Zielspalte in SQL. Die Wörterbücher werden von dieser Erweiterung in einen textuellen HSTORE-Ausdruck konvertiert. Wenn dieses Verhalten unerwünscht ist, deaktivieren Sie die Verwendung der Hstore-Erweiterung, indem Sie use_native_hstore wie folgt auf False setzen.

engine = create_engine(
    "postgresql+psycopg2://scott:tiger@localhost/test",
    use_native_hstore=False,
)

Der HSTORE-Typ wird weiterhin unterstützt, wenn die Erweiterung psycopg2.extensions.register_hstore() nicht verwendet wird. Dies bedeutet lediglich, dass die Umwandlung zwischen Python-Wörterbüchern und dem HSTORE-String-Format, sowohl auf Parameter- als auch auf Ergebnis-Seite, innerhalb der eigenen Marshalling-Logik von SQLAlchemy stattfindet und nicht die von psycopg2, was performanter sein kann.

psycopg

Unterstützung für die PostgreSQL-Datenbank über den psycopg (auch bekannt als psycopg 3) Treiber.

DBAPI

Dokumentation und Download-Informationen (falls zutreffend) für psycopg (auch bekannt als psycopg 3) sind verfügbar unter: https://pypi.org/project/psycopg/

Verbinden

Verbindungszeichenfolge

postgresql+psycopg://user:password@host:port/dbname[?key=value&key=value...]

psycopg ist der Paket- und Modulname für Version 3 des psycopg-Datenbanktreibers, früher bekannt als psycopg2. Dieser Treiber unterscheidet sich stark von seinem Vorgänger psycopg2, sodass SQLAlchemy ihn über einen völlig separaten Dialekt unterstützt; die Unterstützung für psycopg2 wird voraussichtlich so lange bestehen bleiben, wie dieses Paket für moderne Python-Versionen funktioniert, und bleibt auch der Standard-Dialekt für die postgresql://-Dialektserie.

Der SQLAlchemy psycopg-Dialekt bietet sowohl eine synchrone als auch eine asynchrone Implementierung unter demselben Dialektnamen. Die richtige Version wird ausgewählt, je nachdem, wie die Engine erstellt wird.

  • Aufruf von create_engine() mit postgresql+psycopg://... wählt automatisch die synchrone Version aus, z. B.

    from sqlalchemy import create_engine
    
    sync_engine = create_engine(
        "postgresql+psycopg://scott:tiger@localhost/test"
    )
  • Aufruf von create_async_engine() mit postgresql+psycopg://... wählt automatisch die asynchrone Version aus, z. B.

    from sqlalchemy.ext.asyncio import create_async_engine
    
    asyncio_engine = create_async_engine(
        "postgresql+psycopg://scott:tiger@localhost/test"
    )

Die asyncio-Version des Dialekts kann auch explizit mit dem Suffix psycopg_async angegeben werden, wie

from sqlalchemy.ext.asyncio import create_async_engine

asyncio_engine = create_async_engine(
    "postgresql+psycopg_async://scott:tiger@localhost/test"
)

Siehe auch

psycopg2 - Der SQLAlchemy psycopg-Dialekt teilt die meisten seiner Verhaltensweisen mit dem psycopg2-Dialekt. Weitere Dokumentation ist dort verfügbar.

Verwendung einer anderen Cursor-Klasse

Einer der Unterschiede zwischen psycopg und dem älteren psycopg2 liegt in der Handhabung von gebundenen Parametern: psycopg2 bindet sie clientseitig, während psycopg sie standardmäßig serverseitig bindet.

Es ist möglich, psycopg so zu konfigurieren, dass clientseitiges Binden erfolgt, indem cursor_factory auf ClientCursor gesetzt wird, wenn die Engine erstellt wird.

from psycopg import ClientCursor

client_side_engine = create_engine(
    "postgresql+psycopg://...",
    connect_args={"cursor_factory": ClientCursor},
)

Ähnlich wie bei der Verwendung einer asynchronen Engine kann AsyncClientCursor angegeben werden.

from psycopg import AsyncClientCursor

client_side_engine = create_async_engine(
    "postgresql+psycopg://...",
    connect_args={"cursor_factory": AsyncClientCursor},
)

pg8000

Unterstützung für die PostgreSQL-Datenbank über den pg8000-Treiber.

DBAPI

Dokumentation und Download-Informationen (falls zutreffend) für pg8000 sind verfügbar unter: https://pypi.org/project/pg8000/

Verbinden

Verbindungszeichenfolge

postgresql+pg8000://user:password@host:port/dbname[?key=value&key=value...]

Geändert in Version 1.4: Der pg8000-Dialekt wurde für Version 1.16.6 und höher aktualisiert und ist wieder Teil der kontinuierlichen Integration von SQLAlchemy mit voller Funktionsunterstützung.

Unicode

pg8000 kodiert/dekodiert Zeichenkettenwerte zwischen sich und dem Server unter Verwendung des PostgreSQL client_encoding-Parameters; standardmäßig ist dies der Wert in der Datei postgresql.conf, die oft standardmäßig auf SQL_ASCII gesetzt ist. Typischerweise kann dies zu utf-8 geändert werden, als ein nützlicheres Standardverhalten.

# client_encoding = sql_ascii # actually, defaults to database encoding
client_encoding = utf8

Das client_encoding kann für eine Sitzung überschrieben werden, indem die folgende SQL-Anweisung ausgeführt wird:

SET CLIENT_ENCODING TO 'utf8';

SQLAlchemy wird diese SQL-Anweisung bei allen neuen Verbindungen ausführen, basierend auf dem Wert, der an create_engine() über den Parameter client_encoding übergeben wird.

engine = create_engine(
    "postgresql+pg8000://user:pass@host/dbname", client_encoding="utf8"
)

SSL-Verbindungen

pg8000 akzeptiert ein Python SSLContext-Objekt, das über das Wörterbuch create_engine.connect_args angegeben werden kann.

import ssl

ssl_context = ssl.create_default_context()
engine = sa.create_engine(
    "postgresql+pg8000://scott:tiger@192.168.0.199/test",
    connect_args={"ssl_context": ssl_context},
)

Wenn der Server ein automatisch generiertes Zertifikat verwendet, das selbstsigniert ist oder nicht mit dem Hostnamen übereinstimmt (aus Sicht des Clients), kann es auch notwendig sein, die Hostnamenprüfung zu deaktivieren.

import ssl

ssl_context = ssl.create_default_context()
ssl_context.check_hostname = False
ssl_context.verify_mode = ssl.CERT_NONE
engine = sa.create_engine(
    "postgresql+pg8000://scott:tiger@192.168.0.199/test",
    connect_args={"ssl_context": ssl_context},
)

pg8000 Transaktionsisolationslevel

Der pg8000-Dialekt bietet dieselben Einstellungen für das Isolationslevel wie der psycopg2-Dialekt.

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • AUTOCOMMIT

asyncpg

Unterstützung für die PostgreSQL-Datenbank über den asyncpg-Treiber.

DBAPI

Dokumentation und Download-Informationen (falls zutreffend) für asyncpg sind verfügbar unter: https://magicstack.github.io/asyncpg/

Verbinden

Verbindungszeichenfolge

postgresql+asyncpg://user:password@host:port/dbname[?key=value&key=value...]

Der asyncpg-Dialekt ist der erste Python-asynchrone Dialekt von SQLAlchemy.

Unter Verwendung einer speziellen asynchronen Vermittlungsschicht kann der asyncpg-Dialekt als Backend für das Erweiterungspaket SQLAlchemy asyncio verwendet werden.

Dieser Dialekt sollte normalerweise nur mit der Engine-Erstellungsfunktion create_async_engine() verwendet werden.

from sqlalchemy.ext.asyncio import create_async_engine

engine = create_async_engine(
    "postgresql+asyncpg://user:pass@hostname/dbname"
)

Neu in Version 1.4.

Hinweis

Standardmäßig dekodiert asyncpg die Typen json und jsonb nicht und gibt sie als Zeichenketten zurück. SQLAlchemy setzt einen Standard-Typ-Decoder für json und jsonb-Typen unter Verwendung der Python-integrierten Funktion json.loads. Die verwendete JSON-Implementierung kann durch Setzen des Attributs json_deserializer beim Erstellen der Engine mit create_engine() oder create_async_engine() geändert werden.

Mehrfach-Host-Verbindungen

Der asyncpg-Dialekt bietet Unterstützung für mehrere Fallback-Hosts auf dieselbe Weise wie die psycopg2- und psycopg-Dialekte. Die Syntax ist dieselbe und verwendet host=<host>:<port>-Kombinationen als zusätzliche Query-String-Argumente; es gibt jedoch keinen Standardport, daher müssen alle Hosts eine vollständige Portnummer angeben, sonst wird eine Ausnahme ausgelöst.

engine = create_async_engine(
    "postgresql+asyncpg://user:password@/dbname?host=HostA:5432&host=HostB:5432&host=HostC:5432"
)

Für vollständige Hintergründe zu dieser Syntax siehe Festlegen mehrerer Fallback-Hosts.

Neu in Version 2.0.18.

Prepared Statement Cache

Der asyncpg SQLAlchemy-Dialekt verwendet asyncpg.connection.prepare() für alle Anweisungen. Die vorbereiteten Anweisungsobjekte werden nach der Erstellung gecacht, was eine Leistungssteigerung von 10 % oder mehr bei der Anweisungsinvokation zu bewirken scheint. Der Cache befindet sich pro DBAPI-Verbindung, d. h. der primäre Speicher für vorbereitete Anweisungen befindet sich innerhalb von DBAPI-Verbindungen, die im Connection Pool gepoolt sind. Die Größe dieses Caches beträgt standardmäßig 100 Anweisungen pro DBAPI-Verbindung und kann mit dem DBAPI-Argument prepared_statement_cache_size angepasst werden (beachten Sie, dass dieses Argument, obwohl es von SQLAlchemy implementiert wird, Teil des DBAPI-Emulationsabschnitts des asyncpg-Dialekts ist, daher wird es als DBAPI-Argument und nicht als Dialekt-Argument behandelt).

engine = create_async_engine(
    "postgresql+asyncpg://user:pass@hostname/dbname?prepared_statement_cache_size=500"
)

Um den Prepared Statement Cache zu deaktivieren, verwenden Sie den Wert Null.

engine = create_async_engine(
    "postgresql+asyncpg://user:pass@hostname/dbname?prepared_statement_cache_size=0"
)

Neu in Version 1.4.0b2: prepared_statement_cache_size für asyncpg hinzugefügt.

Warnung

Der Datenbanktreiber asyncpg verwendet notwendigerweise Caches für PostgreSQL-Typ-OIDs, die veralten, wenn benutzerdefinierte PostgreSQL-Datentypen wie ENUM-Objekte über DDL-Operationen geändert werden. Zusätzlich können auch vorbereitete Anweisungen selbst, die optional vom SQLAlchemy-Treiber wie oben beschrieben zwischengespeichert werden, "veralten", wenn DDL-Befehle an die PostgreSQL-Datenbank gesendet wurden, die die für eine bestimmte vorbereitete Anweisung relevanten Tabellen oder andere Objekte ändern.

Die SQLAlchemy asyncpg-Dialekt wird diese Caches innerhalb ihres lokalen Prozesses ungültig machen, wenn Anweisungen, die DDL repräsentieren, auf einer lokalen Verbindung gesendet werden. Dies ist jedoch nur innerhalb eines einzelnen Python-Prozesses / Datenbank-Engines steuerbar. Wenn DDL-Änderungen von anderen Datenbank-Engines und/oder Prozessen vorgenommen werden, kann eine laufende Anwendung auf asyncpg-Ausnahmen InvalidCachedStatementError und/oder InternalServerError("cache lookup failed for type <oid>") stoßen, wenn sie auf gepoolte Datenbankverbindungen zugreift, die auf den vorherigen Strukturen operierten. Der SQLAlchemy asyncpg-Dialekt wird sich von diesen Fehlerfällen erholen, wenn der Treiber diese Ausnahmen auslöst, indem er seine internen Caches sowie die des asyncpg-Treibers als Reaktion darauf leert. Er kann sie jedoch nicht verhindern, dass sie überhaupt ausgelöst werden, wenn die zwischengespeicherte vorbereitete Anweisung oder die asyncpg-Typ-Caches veraltet sind, noch kann er die Anweisung wiederholen, da die PostgreSQL-Transaktion ungültig wird, wenn diese Fehler auftreten.

Name vorbereiteter Anweisungen mit PGBouncer

Standardmäßig enumeriert asyncpg vorbereitete Anweisungen in numerischer Reihenfolge, was zu Fehlern führen kann, wenn ein Name bereits für eine andere vorbereitete Anweisung vergeben wurde. Dieses Problem kann auftreten, wenn Ihre Anwendung Datenbank-Proxies wie PgBouncer zur Verwaltung von Verbindungen verwendet. Eine mögliche Lösung ist die Verwendung dynamischer Namen für vorbereitete Anweisungen, die asyncpg jetzt über einen optionalen name-Wert für den Anweisungsnamen unterstützt. Dies ermöglicht es Ihnen, eigene eindeutige Namen zu generieren, die nicht mit vorhandenen Namen kollidieren. Um dies zu erreichen, können Sie eine Funktion bereitstellen, die jedes Mal aufgerufen wird, wenn eine vorbereitete Anweisung vorbereitet wird.

from uuid import uuid4

engine = create_async_engine(
    "postgresql+asyncpg://user:pass@somepgbouncer/dbname",
    poolclass=NullPool,
    connect_args={
        "prepared_statement_name_func": lambda: f"__asyncpg_{uuid4()}__",
    },
)

Warnung

Bei Verwendung von PGBouncer ist es wichtig, um eine Ansammlung nutzloser vorbereiteter Anweisungen in Ihrer Anwendung zu verhindern, die Poolklasse NullPool zu verwenden und PgBouncer so zu konfigurieren, dass es DISCARD beim Zurückgeben von Verbindungen verwendet. Der DISCARD-Befehl wird verwendet, um von der Datenbankverbindung gehaltene Ressourcen freizugeben, einschließlich vorbereiteter Anweisungen. Ohne ordnungsgemäße Einrichtung können sich vorbereitete Anweisungen schnell ansammeln und Leistungsprobleme verursachen.

Deaktivieren des PostgreSQL JIT zur Verbesserung der ENUM-Datentypbehandlung

Asyncpg hat ein Problem bei der Verwendung von PostgreSQL ENUM-Datentypen, bei dem beim Erstellen neuer Datenbankverbindungen eine aufwändige Abfrage ausgeführt werden kann, um Metadaten zu benutzerdefinierten Typen abzurufen, was sich nachweislich negativ auf die Leistung auswirkt. Um dieses Problem zu mildern, kann die PostgreSQL "jit"-Einstellung vom Client unter Verwendung dieser Einstellung, die an create_async_engine() übergeben wird, deaktiviert werden.

engine = create_async_engine(
    "postgresql+asyncpg://user:password@localhost/tmp",
    connect_args={"server_settings": {"jit": "off"}},
)

psycopg2cffi

Unterstützung für die PostgreSQL-Datenbank über den psycopg2cffi-Treiber.

DBAPI

Dokumentation und Download-Informationen (falls zutreffend) für psycopg2cffi sind verfügbar unter: https://pypi.org/project/psycopg2cffi/

Verbinden

Verbindungszeichenfolge

postgresql+psycopg2cffi://user:password@host:port/dbname[?key=value&key=value...]

psycopg2cffi ist eine Anpassung von psycopg2, die CFFI für die C-Schicht verwendet. Dies macht es z. B. für die Verwendung in PyPy geeignet. Die Dokumentation ist wie bei psycopg2.