Microsoft SQL Server

Unterstützung für die Microsoft SQL Server-Datenbank.

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

Unterstützte Microsoft SQL Server-Versionen

Support-Typ

Versionen

Supported version

2012+

Best effort

2005+

DBAPI-Unterstützung

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

Externe Dialekte

Zusätzlich zu den oben genannten DBAPI-Schichten mit nativer SQLAlchemy-Unterstützung gibt es Drittanbieter-Dialekte für andere DBAPI-Schichten, die mit SQL Server kompatibel sind. Siehe die Liste „Externe Dialekte“ auf der Seite Dialekte.

Auto-Inkrement-Verhalten / IDENTITY-Spalten

SQL Server bietet ein sogenanntes „Auto-Inkrement“-Verhalten über das IDENTITY-Konstrukt, das auf jede einzelne Ganzzahlspalte in einer Tabelle angewendet werden kann. SQLAlchemy berücksichtigt IDENTITY im Rahmen seines Standard-„Autoincrement“-Verhaltens für eine Ganzzahl-Primärschlüsselspalte, wie unter Column.autoincrement beschrieben. Das bedeutet, dass die erste Ganzzahl-Primärschlüsselspalte in einer Table standardmäßig als Identitätsspalte betrachtet wird – es sei denn, sie ist mit einer Sequence verknüpft – und als solche DDL generiert.

from sqlalchemy import Table, MetaData, Column, Integer

m = MetaData()
t = Table(
    "t",
    m,
    Column("id", Integer, primary_key=True),
    Column("x", Integer),
)
m.create_all(engine)

Das obige Beispiel generiert die DDL als

CREATE TABLE t (
    id INTEGER NOT NULL IDENTITY,
    x INTEGER NULL,
    PRIMARY KEY (id)
)

Wenn diese Standardgenerierung von IDENTITY nicht gewünscht ist, geben Sie False für das Flag Column.autoincrement auf der ersten Ganzzahl-Primärschlüsselspalte an.

m = MetaData()
t = Table(
    "t",
    m,
    Column("id", Integer, primary_key=True, autoincrement=False),
    Column("x", Integer),
)
m.create_all(engine)

Um das Schlüsselwort IDENTITY zu einer Nicht-Primärschlüsselspalte hinzuzufügen, setzen Sie das Flag Column.autoincrement auf True für das gewünschte Column-Objekt und stellen Sie sicher, dass Column.autoincrement auf False für jede Ganzzahl-Primärschlüsselspalte gesetzt ist.

m = MetaData()
t = Table(
    "t",
    m,
    Column("id", Integer, primary_key=True, autoincrement=False),
    Column("x", Integer, autoincrement=True),
)
m.create_all(engine)

Geändert in Version 1.4: Konstrukt Identity in einer Column hinzugefügt, um die Start- und Inkrementparameter von IDENTITY anzugeben. Diese ersetzen die Verwendung des Sequence-Objekts zur Angabe dieser Werte.

Veraltet seit Version 1.4: Die Parameter mssql_identity_start und mssql_identity_increment für Column sind veraltet und sollten durch ein Identity-Objekt ersetzt werden. Die Angabe beider Wege zur Konfiguration eines IDENTITY führt zu einem Kompilierungsfehler. Diese Optionen werden auch nicht mehr als Teil des Schlüssels dialect_options in Inspector.get_columns() zurückgegeben. Verwenden Sie stattdessen die Informationen unter dem Schlüssel identity.

Veraltet seit Version 1.3: Die Verwendung von Sequence zur Angabe von IDENTITY-Merkmalen ist veraltet und wird in einer zukünftigen Version entfernt. Bitte verwenden Sie die Parameter Identity.start und Identity.increment des Identity-Objekts.

Geändert in Version 1.4: Die Möglichkeit, ein Sequence-Objekt zur Änderung von IDENTITY-Merkmalen zu verwenden, wurde entfernt. Sequence-Objekte manipulieren nun nur noch echte T-SQL SEQUENCE-Typen.

Hinweis

Es kann nur eine IDENTITY-Spalte pro Tabelle geben. Wenn autoincrement=True verwendet wird, um das IDENTITY-Schlüsselwort zu aktivieren, schützt SQLAlchemy nicht vor mehreren Spalten, die die Option gleichzeitig angeben. Die SQL Server-Datenbank lehnt dann die CREATE TABLE-Anweisung ab.

Hinweis

Eine INSERT-Anweisung, die versucht, einen Wert für eine als IDENTITY gekennzeichnete Spalte bereitzustellen, wird von SQL Server abgelehnt. Damit der Wert akzeptiert wird, muss eine Sitzungsoption „SET IDENTITY_INSERT“ aktiviert sein. Der SQLAlchemy SQL Server-Dialekt führt diese Operation automatisch aus, wenn ein Core Insert-Konstrukt verwendet wird; wenn die Ausführung einen Wert für die IDENTITY-Spalte angibt, wird die Option „IDENTITY_INSERT“ für die Dauer dieser Anweisung aktiviert. Dieses Szenario ist jedoch nicht performant und sollte nicht für den normalen Gebrauch herangezogen werden. Wenn eine Tabelle ihr Ganzzahl-Primärschlüsselspalte nicht tatsächlich mit IDENTITY-Verhalten benötigt, sollte das Schlüsselwort beim Erstellen der Tabelle deaktiviert werden, indem sichergestellt wird, dass autoincrement=False gesetzt ist.

„Start“ und „Inkrement“ steuern

Die spezifische Steuerung der Werte „Start“ und „Inkrement“ für den IDENTITY-Generator erfolgt über die Parameter Identity.start und Identity.increment, die dem Identity-Objekt übergeben werden.

from sqlalchemy import Table, Integer, Column, Identity

test = Table(
    "test",
    metadata,
    Column(
        "id", Integer, primary_key=True, Identity(start=100, increment=10)
    ),
    Column("name", String(20)),
)

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

CREATE TABLE test (
  id INTEGER NOT NULL IDENTITY(100,10) PRIMARY KEY,
  name VARCHAR(20) NULL,
)

Hinweis

Das Identity-Objekt unterstützt zusätzlich zu start und increment viele weitere Parameter. Diese werden von SQL Server nicht unterstützt und werden bei der Generierung der CREATE TABLE DDL ignoriert.

Geändert in Version 1.3.19: Das Identity-Objekt wird nun verwendet, um den IDENTITY-Generator für eine Column unter SQL Server zu beeinflussen. Zuvor wurde das Sequence-Objekt verwendet. Da SQL Server nun echte Sequenzen als separates Konstrukt unterstützt, wird Sequence ab SQLAlchemy Version 1.4 auf normale Weise funktional sein.

IDENTITY mit numerischen Nicht-Ganzzahl-Typen verwenden

SQL Server erlaubt auch die Verwendung von IDENTITY mit NUMERIC-Spalten. Um dieses Muster reibungslos in SQLAlchemy zu implementieren, sollte der primäre Datentyp der Spalte weiterhin Integer sein. Die zugrunde liegende Implementierung, die an den SQL Server gesendet wird, kann jedoch als Numeric über TypeEngine.with_variant() angegeben werden.

from sqlalchemy import Column
from sqlalchemy import Integer
from sqlalchemy import Numeric
from sqlalchemy import String
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()


class TestTable(Base):
    __tablename__ = "test"
    id = Column(
        Integer().with_variant(Numeric(10, 0), "mssql"),
        primary_key=True,
        autoincrement=True,
    )
    name = Column(String)

Im obigen Beispiel liefert Integer().with_variant() klare Nutzungsangaben, die die Absicht des Codes genau beschreiben. Die allgemeine Einschränkung, dass autoincrement nur für Integer gilt, wird auf Metadatenebene und nicht auf Dialektebene festgelegt.

Bei Verwendung des obigen Musters ist der primäre Schlüsselbezeichner, der nach dem Einfügen einer Zeile zurückgegeben wird und der Wert, der einem ORM-Objekt wie dem oben genannten TestTable zugewiesen würde, eine Instanz von Decimal() und nicht int bei Verwendung von SQL Server. Der numerische Rückgabetyp des Numeric-Typs kann durch Übergabe von False an Numeric.asdecimal auf floats geändert werden. Um den Rückgabetyp des obigen Numeric(10, 0) so zu normalisieren, dass Python-Integers zurückgegeben werden (die auch „long“-Integer-Werte in Python 3 unterstützen), verwenden Sie TypeDecorator wie folgt.

from sqlalchemy import TypeDecorator


class NumericAsInteger(TypeDecorator):
    "normalize floating point return values into ints"

    impl = Numeric(10, 0, asdecimal=False)
    cache_ok = True

    def process_result_value(self, value, dialect):
        if value is not None:
            value = int(value)
        return value


class TestTable(Base):
    __tablename__ = "test"
    id = Column(
        Integer().with_variant(NumericAsInteger, "mssql"),
        primary_key=True,
        autoincrement=True,
    )
    name = Column(String)

INSERT-Verhalten

Die Handhabung der IDENTITY-Spalte zur INSERT-Zeit beinhaltet zwei wichtige Techniken. Die gebräuchlichste ist die Möglichkeit, den „zuletzt eingefügten Wert“ für eine bestimmte IDENTITY-Spalte abzurufen, ein Prozess, den SQLAlchemy in vielen Fällen implizit durchführt, insbesondere innerhalb des ORM.

Der Prozess zum Abrufen dieses Werts hat mehrere Varianten

  • In den allermeisten Fällen wird RETURNING in Verbindung mit INSERT-Anweisungen auf SQL Server verwendet, um neu generierte Primärschlüsselwerte zu erhalten.

    INSERT INTO t (x) OUTPUT inserted.id VALUES (?)

    Seit SQLAlchemy 2.0 wird standardmäßig auch die Funktion „Insert Many Values“ Verhalten für INSERT-Anweisungen verwendet, um viele Zeilen gleichzeitig einzufügen; für SQL Server gilt diese Funktion sowohl für RETURNING als auch für Nicht-RETURNING INSERT-Anweisungen.

    Geändert in Version 2.0.10: Die Funktion „Insert Many Values“ Verhalten für INSERT-Anweisungen für SQL Server wurde für SQLAlchemy Version 2.0.9 aufgrund von Problemen mit der Zeilenreihenfolge vorübergehend deaktiviert. Ab 2.0.10 ist die Funktion wieder aktiviert, mit Sonderfallbehandlung für die Anforderung des Units of Work, dass RETURNING geordnet sein muss.

  • Wenn RETURNING nicht verfügbar ist oder über implicit_returning=False deaktiviert wurde, werden entweder die Funktion scope_identity() oder die Variable @@identity verwendet; das Verhalten variiert je nach Backend.

    • Bei Verwendung von PyODBC wird der Ausdruck ; select scope_identity() an das Ende der INSERT-Anweisung angehängt; ein zweites Ergebnisset wird abgerufen, um den Wert zu erhalten. Angenommen, eine Tabelle ist wie folgt aufgebaut:

      t = Table(
          "t",
          metadata,
          Column("id", Integer, primary_key=True),
          Column("x", Integer),
          implicit_returning=False,
      )

      eine INSERT-Anweisung würde wie folgt aussehen:

      INSERT INTO t (x) VALUES (?); select scope_identity()
    • Andere Dialekte wie pymssql rufen SELECT scope_identity() AS lastrowid nach einer INSERT-Anweisung auf. Wenn das Flag use_scope_identity=False an create_engine() übergeben wird, wird stattdessen die Anweisung SELECT @@identity AS lastrowid verwendet.

Eine Tabelle, die eine IDENTITY-Spalte enthält, verbietet eine INSERT-Anweisung, die explizit auf die Identitätsspalte verweist. Der SQLAlchemy-Dialekt erkennt, wenn eine mit einem Core insert()-Konstrukt (kein reiner SQL-String) erstellte INSERT-Anweisung auf die Identitätsspalte verweist. In diesem Fall wird SET IDENTITY_INSERT ON vor der INSERT-Anweisung und SET IDENTITY_INSERT OFF nach der Ausführung ausgegeben. Angenommen, dieses Beispiel:

m = MetaData()
t = Table(
    "t", m, Column("id", Integer, primary_key=True), Column("x", Integer)
)
m.create_all(engine)

with engine.begin() as conn:
    conn.execute(t.insert(), {"id": 1, "x": 1}, {"id": 2, "x": 2})

Die obige Spalte wird mit IDENTITY erstellt, jedoch gibt die von uns ausgegebene INSERT-Anweisung explizite Werte an. In der Echo-Ausgabe können wir sehen, wie SQLAlchemy dies handhabt:

CREATE TABLE t (
    id INTEGER NOT NULL IDENTITY(1,1),
    x INTEGER NULL,
    PRIMARY KEY (id)
)

COMMIT
SET IDENTITY_INSERT t ON
INSERT INTO t (id, x) VALUES (?, ?)
((1, 1), (2, 2))
SET IDENTITY_INSERT t OFF
COMMIT

Dies ist ein Hilfsszenario, das für Tests und Bulk-Insert-Szenarien geeignet ist.

SEQUENCE-Unterstützung

Das Sequence-Objekt erstellt „echte“ Sequenzen, d. h. CREATE SEQUENCE.

>>> from sqlalchemy import Sequence
>>> from sqlalchemy.schema import CreateSequence
>>> from sqlalchemy.dialects import mssql
>>> print(
...     CreateSequence(Sequence("my_seq", start=1)).compile(
...         dialect=mssql.dialect()
...     )
... )
CREATE SEQUENCE my_seq START WITH 1

Für die Generierung von Ganzzahl-Primärschlüsseln sollte bei SQL Server im Allgemeinen der IDENTITY-Konstrukt gegenüber der Sequenz bevorzugt werden.

Tipp

Der Standardstartwert für T-SQL ist -2**63 statt 1 wie bei den meisten anderen SQL-Datenbanken. Benutzer sollten Sequence.start explizit auf 1 setzen, wenn dies der erwartete Standard ist.

seq = Sequence("my_sequence", start=1)

Neu in Version 1.4: SQL Server-Unterstützung für Sequence hinzugefügt.

Geändert in Version 2.0: Der SQL Server-Dialekt rendert implizit nicht mehr „START WITH 1“ für CREATE SEQUENCE, was das Verhalten war, das erstmals in Version 1.4 implementiert wurde.

MAX bei VARCHAR / NVARCHAR

SQL Server unterstützt die spezielle Zeichenkette „MAX“ innerhalb der Datentypen VARCHAR und NVARCHAR, um „maximale Länge möglich“ anzugeben. Der Dialekt behandelt dies derzeit als Länge „None“ im Basistyp, anstatt eine Dialekt-spezifische Version dieser Typen bereitzustellen, sodass ein Basistyp wie VARCHAR(None) ohne dialekt-spezifische Typen ein „unbegrenztes“ Verhalten auf mehr als einem Backend annehmen kann.

Um ein SQL Server VARCHAR oder NVARCHAR mit maximaler Länge zu erstellen, verwenden Sie None.

my_table = Table(
    "my_table",
    metadata,
    Column("my_data", VARCHAR(None)),
    Column("my_n_data", NVARCHAR(None)),
)

Collation-Unterstützung

Zeichencollations werden von den grundlegenden Zeichenketten-Typen unterstützt, angegeben durch das String-Argument „collation“.

from sqlalchemy import VARCHAR

Column("login", VARCHAR(32, collation="Latin1_General_CI_AS"))

Wenn eine solche Spalte mit einer Table verknüpft ist, ergibt die CREATE TABLE-Anweisung für diese Spalte:

login VARCHAR(32) COLLATE Latin1_General_CI_AS NULL

LIMIT/OFFSET-Unterstützung

MSSQL hat ab SQL Server 2012 Unterstützung für LIMIT / OFFSET hinzugefügt, über die Klauseln „OFFSET n ROWS“ und „FETCH NEXT n ROWS“. SQLAlchemy unterstützt diese Syntaxen automatisch, wenn SQL Server 2012 oder höher erkannt wird.

Geändert in Version 1.4: Unterstützung für die SQL Server-Syntax „OFFSET n ROWS“ und „FETCH NEXT n ROWS“ hinzugefügt.

Für Anweisungen, die nur LIMIT und kein OFFSET angeben, unterstützen alle Versionen von SQL Server das TOP-Schlüsselwort. Diese Syntax wird für alle SQL Server-Versionen verwendet, wenn keine OFFSET-Klausel vorhanden ist. Eine Anweisung wie

select(some_table).limit(5)

würde ähnlich wie folgt gerendert werden:

SELECT TOP 5 col1, col2.. FROM table

Für Versionen von SQL Server vor SQL Server 2012 wird eine Anweisung, die LIMIT und OFFSET oder nur OFFSET allein verwendet, mit der Fensterfunktion ROW_NUMBER() gerendert. Eine Anweisung wie

select(some_table).order_by(some_table.c.col3).limit(5).offset(10)

würde ähnlich wie folgt gerendert werden:

SELECT anon_1.col1, anon_1.col2 FROM (SELECT col1, col2,
ROW_NUMBER() OVER (ORDER BY col3) AS
mssql_rn FROM table WHERE t.x = :x_1) AS
anon_1 WHERE mssql_rn > :param_1 AND mssql_rn <= :param_2 + :param_1

Beachten Sie, dass bei Verwendung von LIMIT und/oder OFFSET, sei es mit älterer oder neuerer SQL Server-Syntax, die Anweisung auch eine ORDER BY-Klausel haben muss, andernfalls wird ein CompileError ausgelöst.

DDL-Kommentar-Unterstützung

Kommentarunterstützung, einschließlich DDL-Rendering für Attribute wie Table.comment und Column.comment, sowie die Möglichkeit, diese Kommentare zu reflektieren, wird vorausgesetzt, dass eine unterstützte Version von SQL Server verwendet wird. Wenn eine nicht unterstützte Version wie Azure Synapse beim ersten Verbindungsaufbau erkannt wird (basierend auf der Anwesenheit der SQL-Funktion fn_listextendedproperty), wird die Kommentarunterstützung, einschließlich Rendering und Tabellenkommentar-Reflektion, deaktiviert, da beide Funktionen auf SQL Server-Stored Procedures und Funktionen angewiesen sind, die nicht auf allen Backend-Typen verfügbar sind.

Um die Kommentarunterstützung zu erzwingen oder zu deaktivieren und die automatische Erkennung zu umgehen, setzen Sie den Parameter supports_comments innerhalb von create_engine().

e = create_engine("mssql+pyodbc://u:p@dsn", supports_comments=False)

Neu in Version 2.0: Unterstützung für Tabellen- und Spaltenkommentare für den SQL Server-Dialekt, einschließlich DDL-Generierung und Reflexion, hinzugefügt.

Transaktionsisolationslevel

Alle SQL Server-Dialekte unterstützen die Einstellung der Transaktionsisolationsstufe sowohl über einen Dialekt-spezifischen Parameter create_engine.isolation_level, der von create_engine() akzeptiert wird, als auch über das Argument Connection.execution_options.isolation_level, das an Connection.execution_options() übergeben wird. Diese Funktion funktioniert, indem der Befehl SET TRANSACTION ISOLATION LEVEL <level> für jede neue Verbindung ausgegeben wird.

Isolationslevel mit create_engine() einstellen

engine = create_engine(
    "mssql+pyodbc://scott:tiger@ms_2008", isolation_level="REPEATABLE READ"
)

Einstellung über per-Verbindungs-Ausführungsoptionen

connection = engine.connect()
connection = connection.execution_options(isolation_level="READ COMMITTED")

Gültige Werte für isolation_level sind

  • AUTOCOMMIT - pyodbc / pymssql-spezifisch

  • READ COMMITTED

  • READ UNCOMMITTED

  • REPEATABLE READ

  • SERIALIZABLE

  • SNAPSHOT - spezifisch für SQL Server

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.

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

Die von SQLAlchemy Engine verwendete Connection-Pool-Implementierung QueuePool beinhaltet das Verhalten reset on return, das beim Zurückgeben von Verbindungen an den Pool die DBAPI-Methode .rollback() aufruft. Während dieser Rollback den sofortigen Zustand der vorherigen Transaktion löscht, deckt er keine breitere Palette von Sitzungszuständen ab, einschließlich temporärer Tabellen sowie anderer Serverzustände wie Prepared Statement Handles und Statement Caches. Ein undokumentiertes SQL Server-Verfahren namens sp_reset_connection ist als Workaround für dieses Problem bekannt, das den Großteil des Sitzungszustands zurücksetzt, der sich in einer Verbindung ansammelt, einschließlich temporärer Tabellen.

Um sp_reset_connection als Mittel zur Durchführung von Reset-on-Return zu installieren, kann der PoolEvents.reset() Event-Hook verwendet werden, wie im folgenden Beispiel gezeigt. Der Parameter create_engine.pool_reset_on_return wird auf None gesetzt, damit das benutzerdefinierte Schema das Standardverhalten vollständig ersetzen kann. Der benutzerdefinierte Hook ruft in jedem Fall .rollback() auf, da es normalerweise wichtig ist, dass die eigene Nachverfolgung von Commit/Rollback durch den DBAPI mit dem Transaktionszustand übereinstimmt.

from sqlalchemy import create_engine
from sqlalchemy import event

mssql_engine = create_engine(
    "mssql+pyodbc://scott:tiger^5HHH@mssql2017:1433/test?driver=ODBC+Driver+17+for+SQL+Server",
    # disable default reset-on-return scheme
    pool_reset_on_return=None,
)


@event.listens_for(mssql_engine, "reset")
def _reset_mssql(dbapi_connection, connection_record, reset_state):
    if not reset_state.terminate_only:
        dbapi_connection.execute("{call sys.sp_reset_connection}")

    # 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 wurden dem PoolEvents.reset() Event hinzugefügt und es wird zusätzlich sichergestellt, dass das Event für alle „Reset“-Vorkommen aufgerufen wird, so dass es als Ort für benutzerdefinierte „Reset“-Handler geeignet ist. Vorherige Schemata, die den PoolEvents.checkin()-Handler verwenden, bleiben ebenfalls nutzbar.

Siehe auch

Reset On Return - in der Dokumentation zu Connection Pooling.

Nullbarkeit

MSSQL unterstützt drei Stufen der Spaltennullbarkeit. Die Standard-Nullbarkeit erlaubt NULLs und ist explizit im CREATE TABLE-Konstrukt:

name VARCHAR(20) NULL

Wenn nullable=None angegeben wird, erfolgt keine Spezifikation. Mit anderen Worten, der konfigurierte Standardwert der Datenbank wird verwendet. Dies wird gerendert:

name VARCHAR(20)

Wenn nullable True oder False ist, wird die Spalte entsprechend NULL oder NOT NULL.

Datums- / Zeitbehandlung

DATE und TIME werden unterstützt. Bindungsparameter werden in datetime.datetime()-Objekte umgewandelt, wie von den meisten MSSQL-Treibern erforderlich, und Ergebnisse werden bei Bedarf aus Zeichenketten verarbeitet. Die Datentypen DATE und TIME sind für MSSQL 2005 und älter nicht verfügbar – wenn eine Serverversion unter 2008 erkannt wird, wird die DDL für diese Typen als DATETIME ausgegeben.

Veraltung großer Text-/Binärtypen

Laut der SQL Server 2012/2014 Dokumentation werden die Datentypen NTEXT, TEXT und IMAGE in einer zukünftigen Version aus SQL Server entfernt. SQLAlchemy ordnet diese Typen normalerweise den Datentypen UnicodeText, TextClause und LargeBinary zu.

Um diese Änderung zu berücksichtigen, wird dem Dialekt ein neues Flag deprecate_large_types hinzugefügt, das automatisch basierend auf der Erkennung der verwendeten Serverversion gesetzt wird, sofern es nicht vom Benutzer anderweitig gesetzt wurde. Das Verhalten dieses Flags ist wie folgt:

  • Wenn dieses Flag True ist, rendern die Datentypen UnicodeText, TextClause und LargeBinary beim Rendern von DDL die Typen NVARCHAR(max), VARCHAR(max) bzw. VARBINARY(max). Dies ist ein neues Verhalten ab der Einführung dieses Flags.

  • Wenn dieses Flag False ist, rendern die Datentypen UnicodeText, TextClause und LargeBinary beim Rendern von DDL die Typen NTEXT, TEXT bzw. IMAGE. Dies ist das langjährige Verhalten dieser Typen.

  • Das Flag hat zunächst den Wert None, bevor eine Datenbankverbindung hergestellt wird. Wenn der Dialekt zum Rendern von DDL verwendet wird, ohne dass das Flag gesetzt ist, wird dies genauso interpretiert wie False.

  • Bei der ersten Verbindung erkennt der Dialekt, ob SQL Server Version 2012 oder neuer verwendet wird. Wenn das Flag immer noch None ist, wird es auf True oder False gesetzt, je nachdem, ob 2012 oder neuer erkannt wurde.

  • Das Flag kann beim Erstellen des Dialekts entweder auf True oder False gesetzt werden, typischerweise über create_engine().

    eng = create_engine(
        "mssql+pymssql://user:pass@host/db", deprecate_large_types=True
    )
  • Volle Kontrolle darüber, ob die "alten" oder "neuen" Typen gerendert werden, ist in allen SQLAlchemy-Versionen durch die Verwendung der Großbuchstaben-Typobjekte möglich: NVARCHAR, VARCHAR, VARBINARY, TEXT, NTEXT, IMAGE bleiben immer fest und geben immer genau diesen Typ aus.

Mehrteilige Schemanamen

SQL Server-Schemas erfordern manchmal mehrere Teile für ihren "Schema"-Qualifizierer, d. h. die Einbeziehung des Datenbanknamens und des Besitzernamens als separate Tokens, wie z. B. meinedatenbank.dbo.eine_tabelle. Diese mehrteiligen Namen können auf einmal mithilfe des Arguments Table.schema von Table gesetzt werden.

Table(
    "some_table",
    metadata,
    Column("q", String(50)),
    schema="mydatabase.dbo",
)

Bei Operationen wie Tabellen- oder Komponentenreflexion wird ein Schemeargument, das einen Punkt enthält, in separate "Datenbank"- und "Besitzer"-Komponenten aufgeteilt, um die SQL Server Information Schema-Tabellen korrekt abzufragen, da diese beiden Werte separat gespeichert sind. Darüber hinaus werden beim Rendern des Schemanamens für DDL oder SQL die beiden Komponenten für Fälle mit Groß-/Kleinschreibung und andere Sonderzeichen separat maskiert. Angenommen, das folgende Argument:

Table(
    "some_table",
    metadata,
    Column("q", String(50)),
    schema="MyDataBase.dbo",
)

Das obige Schema würde als [MyDataBase].dbo gerendert und bei der Reflexion auch als "dbo" als Besitzer und "MyDataBase" als Datenbankname reflektiert werden.

Um zu steuern, wie der Schemaname in Datenbank / Besitzer aufgeteilt wird, geben Sie Klammern (die in SQL Server Maskierungszeichen sind) im Namen an. Unten wird "Besitzer" als MyDataBase.dbo betrachtet und "Datenbank" ist None.

Table(
    "some_table",
    metadata,
    Column("q", String(50)),
    schema="[MyDataBase.dbo]",
)

Um Datenbank- und Besitzernamen mit Sonderzeichen oder eingebetteten Punkten einzeln anzugeben, verwenden Sie zwei Klammerpaare.

Table(
    "some_table",
    metadata,
    Column("q", String(50)),
    schema="[MyDataBase.Period].[MyOwner.Dot]",
)

Geändert in Version 1.2: Der SQL Server-Dialekt behandelt nun Klammern als Bezeichner-Trennzeichen, die das Schema in separate Datenbank- und Besitzer-Tokens aufteilen, um Punkte innerhalb der Namen selbst zu ermöglichen.

Legacy-Schemamodus

Sehr alte Versionen des MSSQL-Dialekts führten das Verhalten ein, dass eine Schema-qualifizierte Tabelle in einer SELECT-Anweisung automatisch als Alias behandelt wurde. Angenommen, eine Tabelle

account_table = Table(
    "account",
    metadata,
    Column("id", Integer, primary_key=True),
    Column("info", String(100)),
    schema="customer_schema",
)

Dieser Legacy-Modus des Renderns würde davon ausgehen, dass "customer_schema.account" nicht von allen Teilen der SQL-Anweisung akzeptiert würde, wie unten dargestellt.

>>> eng = create_engine("mssql+pymssql://mydsn", legacy_schema_aliasing=True)
>>> print(account_table.select().compile(eng))
SELECT account_1.id, account_1.info FROM customer_schema.account AS account_1

Dieser Verhaltensmodus ist nun standardmäßig deaktiviert, da er keinen Zweck zu erfüllen scheint. Falls ältere Anwendungen ihn jedoch benötigen, ist er über das Argument legacy_schema_aliasing für create_engine() verfügbar, wie oben gezeigt.

Veraltet seit Version 1.4: Das Flag legacy_schema_aliasing ist nun veraltet und wird in einer zukünftigen Version entfernt.

Unterstützung für Clustered Indexes

Der MSSQL-Dialekt unterstützt Clustered Indexes (und Primärschlüssel) über die Option mssql_clustered. Diese Option ist für Index, UniqueConstraint und PrimaryKeyConstraint verfügbar. Für Indizes kann diese Option mit mssql_columnstore kombiniert werden, um einen Clustered Columnstore Index zu erstellen.

Um einen Clustered Index zu generieren

Index("my_index", table.c.x, mssql_clustered=True)

was den Index als CREATE CLUSTERED INDEX my_index ON table (x) rendert.

Um einen Clustered Primary Key zu generieren, verwenden Sie

Table(
    "my_table",
    metadata,
    Column("x", ...),
    Column("y", ...),
    PrimaryKeyConstraint("x", "y", mssql_clustered=True),
)

was die Tabelle beispielsweise als

CREATE TABLE my_table (
  x INTEGER NOT NULL,
  y INTEGER NOT NULL,
  PRIMARY KEY CLUSTERED (x, y)
)

Ebenso können wir eine Clustered Unique Constraint mit

Table(
    "my_table",
    metadata,
    Column("x", ...),
    Column("y", ...),
    PrimaryKeyConstraint("x"),
    UniqueConstraint("y", mssql_clustered=True),
)

Um einen Non-Clustered Primary Key explizit anzufordern (z. B. wenn ein separater Clustered Index gewünscht wird), verwenden Sie

Table(
    "my_table",
    metadata,
    Column("x", ...),
    Column("y", ...),
    PrimaryKeyConstraint("x", "y", mssql_clustered=False),
)

was die Tabelle beispielsweise als

CREATE TABLE my_table (
  x INTEGER NOT NULL,
  y INTEGER NOT NULL,
  PRIMARY KEY NONCLUSTERED (x, y)
)

Unterstützung für Columnstore Indexes

Der MSSQL-Dialekt unterstützt Columnstore Indexes über die Option mssql_columnstore. Diese Option ist für Index verfügbar. Sie kann mit der Option mssql_clustered kombiniert werden, um einen Clustered Columnstore Index zu erstellen.

Um einen Columnstore Index zu generieren

Index("my_index", table.c.x, mssql_columnstore=True)

was den Index als CREATE COLUMNSTORE INDEX my_index ON table (x) rendert.

Um einen Clustered Columnstore Index zu generieren, geben Sie keine Spalten an

idx = Index("my_index", mssql_clustered=True, mssql_columnstore=True)
# required to associate the index with the table
table.append_constraint(idx)

das obige rendert den Index als CREATE CLUSTERED COLUMNSTORE INDEX my_index ON table.

Neu in Version 2.0.18.

MSSQL-spezifische Indexoptionen

Zusätzlich zur Clusterbildung unterstützt der MSSQL-Dialekt weitere spezielle Optionen für Index.

INCLUDE

Die Option mssql_include rendert INCLUDE(spaltenname) für die angegebenen Zeichenkettennamen.

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

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

Gefilterte Indizes

Die Option mssql_where rendert WHERE(bedingung) für die angegebenen Zeichenkettennamen.

Index("my_index", table.c.x, mssql_where=table.c.x > 10)

würde den Index als CREATE INDEX my_index ON table (x) WHERE x > 10 rendern.

Neu in Version 1.3.4.

Indexsortierung

Die Indexsortierung ist über funktionale Ausdrücke verfügbar, wie z. B.:

Index("my_index", table.c.x.desc())

würde den Index als CREATE INDEX my_index ON table (x DESC) rendern.

Siehe auch

Funktionale Indizes

Kompatibilitätsstufen

MSSQL unterstützt die Festlegung von Kompatibilitätsstufen auf Datenbankebene. Dies ermöglicht beispielsweise die Ausführung einer Datenbank, die mit SQL2000 kompatibel ist, während sie auf einem SQL2005-Datenbankserver läuft. server_version_info gibt immer die Version des Datenbankservers zurück (in diesem Fall SQL2005) und nicht die Kompatibilitätsstufe. Aus diesem Grund kann SQLAlchemy versuchen, T-SQL-Anweisungen zu verwenden, die vom Datenbankserver nicht analysiert werden können, wenn unter einem Rückwärtskompatibilitätsmodus ausgeführt wird.

Trigger

SQLAlchemy verwendet standardmäßig OUTPUT INSERTED, um neu generierte Primärschlüsselwerte über IDENTITY-Spalten oder andere serverseitige Standardwerte zu erhalten. MS-SQL erlaubt die Verwendung von OUTPUT INSERTED nicht für Tabellen mit Triggern. Um die Verwendung von OUTPUT INSERTED pro Tabelle zu deaktivieren, geben Sie implicit_returning=False für jede Table an, die Trigger hat.

Table(
    "mytable",
    metadata,
    Column("id", Integer, primary_key=True),
    # ...,
    implicit_returning=False,
)

Deklarative Form

class MyClass(Base):
    # ...
    __table_args__ = {"implicit_returning": False}

Zeilenanzahl-Unterstützung / ORM-Versioning

Die SQL Server-Treiber können möglicherweise die Anzahl der von einer UPDATE- oder DELETE-Anweisung betroffenen Zeilen nur begrenzt zurückgeben.

Zum Zeitpunkt der Erstellung dieses Dokuments kann der PyODBC-Treiber keine Zeilenanzahl zurückgeben, wenn OUTPUT INSERTED verwendet wird. Frühere Versionen von SQLAlchemy hatten daher Einschränkungen für Funktionen wie die "ORM-Versioning"-Funktion, die genaue Zeilenanzahlen benötigt, um Versionsnummern mit gefundenen Zeilen abzugleichen.

SQLAlchemy 2.0 ruft nun für diese speziellen Anwendungsfälle die "Zeilenanzahl" manuell ab, indem die Zeilen gezählt werden, die innerhalb von RETURNING zurückkamen. Während der Treiber also immer noch diese Einschränkung hat, ist die ORM-Versioning-Funktion davon nicht mehr betroffen. Ab SQLAlchemy 2.0.5 ist das ORM-Versioning für den pyodbc-Treiber vollständig wiederhergestellt.

Geändert in Version 2.0.5: Die Unterstützung für ORM-Versioning ist für den pyodbc-Treiber wiederhergestellt. Zuvor wurde während des ORM-Flushens eine Warnung ausgegeben, dass das Versioning nicht unterstützt wurde.

Aktivieren der Snapshot-Isolation

SQL Server hat einen Standard-Transaktionsisolationsmodus, der ganze Tabellen sperrt und selbst mäßig gleichzeitige Anwendungen zu lang anhaltenden Sperren und häufigen Deadlocks führt. Die Aktivierung der Snapshot-Isolation für die Datenbank als Ganzes wird für moderne Ebenen der Gleichzeitigkeitsunterstützung empfohlen. Dies geschieht über die folgenden ALTER DATABASE-Befehle, die an der SQL-Eingabeaufforderung ausgeführt werden.

ALTER DATABASE MyDatabase SET ALLOW_SNAPSHOT_ISOLATION ON

ALTER DATABASE MyDatabase SET READ_COMMITTED_SNAPSHOT ON

Hintergrundinformationen zur SQL Server-Snapshot-Isolation finden Sie unter https://msdn.microsoft.com/en-us/library/ms175095.aspx.

SQL Server SQL-Konstrukte

Objektname Beschreibung

try_cast(expression, type_)

Erzeugt einen TRY_CAST-Ausdruck für Backends, die ihn unterstützen; dies ist ein CAST, das NULL für nicht konvertierbare Umwandlungen zurückgibt.

function sqlalchemy.dialects.mssql.try_cast(expression: _ColumnExpressionOrLiteralArgument[Any], type_: _TypeEngineArgument[_T]) TryCast[_T]

Erzeugt einen TRY_CAST-Ausdruck für Backends, die ihn unterstützen; dies ist ein CAST, das NULL für nicht konvertierbare Umwandlungen zurückgibt.

In SQLAlchemy wird dieses Konstrukt **nur** vom SQL Server-Dialekt unterstützt und löst einen CompileError aus, wenn es auf anderen enthaltenen Backends verwendet wird. Drittanbieter-Backends können dieses Konstrukt jedoch ebenfalls unterstützen.

Tipp

Da try_cast() aus dem SQL Server-Dialekt stammt, ist es sowohl von sqlalchemy. als auch von sqlalchemy.dialects.mssql importierbar.

try_cast() gibt eine Instanz von TryCast zurück und verhält sich im Allgemeinen ähnlich wie das Cast-Konstrukt; auf SQL-Ebene ist der Unterschied zwischen CAST und TRY_CAST, dass TRY_CAST NULL für einen nicht konvertierbaren Ausdruck zurückgibt, z. B. wenn versucht wird, einen String "hi" in einen Integerwert zu konvertieren.

Z. B.

from sqlalchemy import select, try_cast, Numeric

stmt = select(try_cast(product_table.c.unit_price, Numeric(10, 4)))

Das obige würde auf Microsoft SQL Server als

SELECT TRY_CAST (product_table.unit_price AS NUMERIC(10, 4))
FROM product_table

Neu in Version 2.0.14: try_cast() wurde vom SQL Server-Dialekt auf ein allgemeines Konstrukt verallgemeinert, das von zusätzlichen Dialekten unterstützt werden kann.

SQL Server Datentypen

Wie bei allen SQLAlchemy-Dialekten sind alle Großbuchstaben-Typen, die als mit SQL Server gültig bekannt sind, vom obersten Dialekt importierbar, unabhängig davon, ob sie aus sqlalchemy.types oder aus dem lokalen Dialekt stammen.

from sqlalchemy.dialects.mssql import (
    BIGINT,
    BINARY,
    BIT,
    CHAR,
    DATE,
    DATETIME,
    DATETIME2,
    DATETIMEOFFSET,
    DECIMAL,
    DOUBLE_PRECISION,
    FLOAT,
    IMAGE,
    INTEGER,
    JSON,
    MONEY,
    NCHAR,
    NTEXT,
    NUMERIC,
    NVARCHAR,
    REAL,
    SMALLDATETIME,
    SMALLINT,
    SMALLMONEY,
    SQL_VARIANT,
    TEXT,
    TIME,
    TIMESTAMP,
    TINYINT,
    UNIQUEIDENTIFIER,
    VARBINARY,
    VARCHAR,
)

Typen, die spezifisch für SQL Server sind oder Argumente mit SQL Server-spezifischer Konstruktion haben, sind wie folgt:

Objektname Beschreibung

BIT

MSSQL BIT Typ.

DATETIME2

DATETIMEOFFSET

DOUBLE_PRECISION

Der SQL-Datentyp DOUBLE PRECISION.

IMAGE

JSON

MSSQL JSON Typ.

MONEY

NTEXT

MSSQL NTEXT Typ, für Unicode-Text mit variabler Länge bis zu 2^30 Zeichen.

REAL

Der SQL-Datentyp REAL.

ROWVERSION

Implementiert den SQL Server ROWVERSION Typ.

SMALLDATETIME

SMALLMONEY

SQL_VARIANT

TIME

TIMESTAMP

Implementiert den SQL Server TIMESTAMP Typ.

TINYINT

UNIQUEIDENTIFIER

XML

MSSQL XML Typ.

class sqlalchemy.dialects.mssql.BIT

MSSQL BIT Typ.

Sowohl pyodbc als auch pymssql geben Werte aus BIT-Spalten als Python <class ‘bool’> zurück, daher erbt es einfach von Boolean.

Mitglieder

__init__()

method sqlalchemy.dialects.mssql.BIT.__init__(create_constraint: bool = False, name: str | None = None, _create_events: bool = True, _adapted_from: SchemaType | None = None)

vererbt von der sqlalchemy.types.Boolean.__init__ Methode von Boolean

Konstruiert ein Boolean.

Parameter:
  • create_constraint

    standardmäßig False. Wenn das Boolean als int/smallint generiert wird, wird auch eine CHECK-Beschränkung für die Tabelle erstellt, die 1 oder 0 als Wert sicherstellt.

    Hinweis

    Es wird dringend empfohlen, dass die CHECK-Beschränkung einen expliziten Namen hat, um Schemaverwaltungsanliegen zu unterstützen. Dies kann entweder durch Setzen des Parameters Boolean.name oder durch Einrichten einer entsprechenden Benennungskonvention erfolgen; siehe Konfiguration von Namenskonventionen für Beschränkungen für Hintergrundinformationen.

    Geändert in Version 1.4: - dieses Flag ist jetzt standardmäßig False, d.h. es wird keine CHECK-Beschränkung für einen nicht-nativen Aufzählungstyp generiert.

  • name – Wenn eine CHECK-Beschränkung generiert wird, geben Sie den Namen der Beschränkung an.

class sqlalchemy.dialects.mssql.CHAR

Der SQL CHAR-Typ.

Klassensignatur

class sqlalchemy.dialects.mssql.CHAR (sqlalchemy.types.String)

method sqlalchemy.dialects.mssql.CHAR.__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, a length for the column for use in DDL and CAST expressions. May be safely omitted if no CREATE TABLE will be issued. Certain databases may require a length for use in DDL, and will raise an exception when the CREATE TABLE DDL is issued if a VARCHAR with no length is included. Whether the value is interpreted as bytes or characters is database specific.

  • 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.

class sqlalchemy.dialects.mssql.DATETIME2

Klassensignatur

class sqlalchemy.dialects.mssql.DATETIME2 (sqlalchemy.dialects.mssql.base._DateTimeBase, sqlalchemy.types.DateTime)

class sqlalchemy.dialects.mssql.DATETIMEOFFSET

Klassensignatur

class sqlalchemy.dialects.mssql.DATETIMEOFFSET (sqlalchemy.dialects.mssql.base._DateTimeBase, sqlalchemy.types.DateTime)

class sqlalchemy.dialects.mssql.DOUBLE_PRECISION

Der SQL-Datentyp DOUBLE PRECISION.

Neu in Version 2.0.11.

class sqlalchemy.dialects.mssql.IMAGE

Mitglieder

__init__()

method sqlalchemy.dialects.mssql.IMAGE.__init__(length: int | None = None)

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

Konstruiert einen LargeBinary-Typ.

Parameter:

length – optional, a length for the column for use in DDL statements, for those binary types that accept a length, such as the MySQL BLOB type.

class sqlalchemy.dialects.mssql.JSON

MSSQL JSON Typ.

MSSQL unterstützt JSON-formatierten Daten ab SQL Server 2016.

Der JSON-Datentyp wird auf DDL-Ebene als NVARCHAR(max) dargestellt, bietet jedoch JSON-Vergleichsfunktionen sowie Python-Koerzierungsverhalten.

JSON wird automatisch verwendet, wenn der Basis-JSON-Datentyp auf einem SQL Server-Backend verwendet wird.

Siehe auch

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

Der JSON-Typ unterstützt die Persistenz von JSON-Werten sowie die Kern-Indexoperationen, die von JSON bereitgestellt werden, indem die Operationen an die JSON_VALUE- oder JSON_QUERY-Funktionen auf Datenbankebene angepasst werden.

Der SQL Server JSON-Typ verwendet notwendigerweise die Funktionen JSON_QUERY und JSON_VALUE bei der Abfrage von Elementen eines JSON-Objekts. Diese beiden Funktionen haben eine große Einschränkung, da sie gegenseitig ausschließend sind, basierend auf dem Typ des zurückzugebenden Objekts. Die Funktion JSON_QUERY gibt **nur** ein JSON-Dictionary oder eine Liste zurück, aber kein einzelnes String-, numerisches oder boolesches Element; die Funktion JSON_VALUE gibt **nur** ein einzelnes String-, numerisches oder boolesches Element zurück. **Beide Funktionen geben entweder NULL zurück oder lösen einen Fehler aus, wenn sie nicht gegen den korrekten erwarteten Wert verwendet werden**.

Um diese ungünstige Anforderung zu erfüllen, gelten folgende Regeln für den Indexzugriff:

  1. Beim Extrahieren eines Unterelements aus einem JSON, das selbst ein JSON-Dictionary oder eine Liste ist, sollte der Comparator.as_json()-Accessor verwendet werden.

    stmt = select(data_table.c.data["some key"].as_json()).where(
        data_table.c.data["some key"].as_json() == {"sub": "structure"}
    )
  2. Beim Extrahieren eines Unterelements aus einem JSON, das ein einfacher boolescher Wert, eine Zeichenkette, eine Ganzzahl oder eine Fließkommazahl ist, verwenden Sie die entsprechende Methode unter Comparator.as_boolean(), Comparator.as_string(), Comparator.as_integer(), Comparator.as_float()

    stmt = select(data_table.c.data["some key"].as_string()).where(
        data_table.c.data["some key"].as_string() == "some string"
    )

Neu in Version 1.4.

Mitglieder

__init__()

methode sqlalchemy.dialects.mssql.JSON.__init__(none_as_null: bool = False)

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

Erstellt einen JSON-Typ.

Parameter:

none_as_null=False

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 null()-Konstrukt immer noch verwendet werden kann, um einen NULL-Wert zu speichern, der direkt als Parameterwert übergeben werden kann und vom JSON-Typ speziell als SQL NULL interpretiert wird.

from sqlalchemy import null

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

Hinweis

JSON.none_as_null gilt nicht für die an Column.default und Column.server_default übergebenen Werte; ein für diese Parameter übergebener Wert von None bedeutet „kein Standardwert vorhanden“.

Zusätzlich gilt bei Verwendung in SQL-Vergleichsausdrücken der Python-Wert None weiterhin für SQL null und nicht für JSON NULL. Das Flag JSON.none_as_null bezieht sich explizit auf die Speicherung des Werts in einer INSERT- oder UPDATE-Anweisung. Der Wert JSON.NULL sollte für SQL-Ausdrücke verwendet werden, die mit JSON null verglichen werden sollen.

Siehe auch

JSON.NULL

klasse sqlalchemy.dialects.mssql.MONEY
klasse sqlalchemy.dialects.mssql.NCHAR

Der SQL NCHAR-Typ.

Klassensignatur

class sqlalchemy.dialects.mssql.NCHAR (sqlalchemy.types.Unicode)

methode sqlalchemy.dialects.mssql.NCHAR.__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 keine 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 ausgegeben wird, wenn eine VARCHAR ohne Länge enthalten ist. 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.mssql.NTEXT

MSSQL NTEXT Typ, für Unicode-Text mit variabler Länge bis zu 2^30 Zeichen.

Mitglieder

__init__()

methode sqlalchemy.dialects.mssql.NTEXT.__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 keine 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 ausgegeben wird, wenn eine VARCHAR ohne Länge enthalten ist. 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.mssql.NVARCHAR

Der SQL NVARCHAR-Typ.

Klassensignatur

class sqlalchemy.dialects.mssql.NVARCHAR (sqlalchemy.types.Unicode)

methode sqlalchemy.dialects.mssql.NVARCHAR.__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 keine 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 ausgegeben wird, wenn eine VARCHAR ohne Länge enthalten ist. 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.mssql.REAL

Der SQL-Datentyp REAL.

klasse sqlalchemy.dialects.mssql.ROWVERSION

Implementiert den SQL Server ROWVERSION Typ.

Der ROWVERSION-Datentyp ist ein SQL Server-Alias für den TIMESTAMP-Datentyp, jedoch legen die aktuellen SQL Server-Dokumentationen nahe, ROWVERSION für neue Datentypen zukünftig zu verwenden.

Der ROWVERSION-Datentyp wird nicht von der Datenbank als solcher reflektiert (z. B. introspektiert); der zurückgegebene Datentyp ist TIMESTAMP.

Dies ist ein schreibgeschützter Datentyp, der das Einfügen von Werten nicht unterstützt.

Neu seit Version 1.2.

Siehe auch

TIMESTAMP

Mitglieder

__init__()

methode sqlalchemy.dialects.mssql.ROWVERSION.__init__(convert_int=False)

geerbt von der sqlalchemy.dialects.mssql.base.TIMESTAMP.__init__ Methode von TIMESTAMP

Erstellt einen TIMESTAMP- oder ROWVERSION-Typ.

Parameter:

convert_int – wenn True, werden binäre Ganzzahlwerte beim Lesen in Ganzzahlen konvertiert.

Neu seit Version 1.2.

klasse sqlalchemy.dialects.mssql.SMALLDATETIME

Mitglieder

__init__()

Klassensignatur

class sqlalchemy.dialects.mssql.SMALLDATETIME (sqlalchemy.dialects.mssql.base._DateTimeBase, sqlalchemy.types.DateTime)

methode sqlalchemy.dialects.mssql.SMALLDATETIME.__init__(timezone: bool = False)

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

Erstellt ein neues DateTime.

Parameter:

timezone – boolesch. Zeigt an, dass der Datetime-Typ die Zeitzonenunterstützung aktivieren soll, falls verfügbar im nur auf dem Basis-Datums-/Zeitdatentyp. Es wird empfohlen, den TIMESTAMP-Datentyp direkt zu verwenden, wenn dieses Flag verwendet wird, da einige Datenbanken separate generische Datums-/Zeitdatentypen enthalten, die sich vom zeitzonenfähigen TIMESTAMP-Datentyp unterscheiden, wie z. B. Oracle Database.

klasse sqlalchemy.dialects.mssql.SMALLMONEY
klasse sqlalchemy.dialects.mssql.SQL_VARIANT
klasse sqlalchemy.dialects.mssql.TEXT

Der SQL TEXT-Typ.

Klassensignatur

class sqlalchemy.dialects.mssql.TEXT (sqlalchemy.types.Text)

methode sqlalchemy.dialects.mssql.TEXT.__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 keine 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 ausgegeben wird, wenn eine VARCHAR ohne Länge enthalten ist. 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.mssql.TIME
klasse sqlalchemy.dialects.mssql.TIMESTAMP

Implementiert den SQL Server TIMESTAMP Typ.

Beachten Sie, dass dies völlig anders ist als der SQL-Standard-TIMESTAMP-Typ, der von SQL Server nicht unterstützt wird. Es handelt sich um einen schreibgeschützten Datentyp, der das Einfügen von Werten nicht unterstützt.

Neu seit Version 1.2.

Siehe auch

ROWVERSION

Mitglieder

__init__()

Klassensignatur

class sqlalchemy.dialects.mssql.TIMESTAMP (sqlalchemy.types._Binary)

methode sqlalchemy.dialects.mssql.TIMESTAMP.__init__(convert_int=False)

Erstellt einen TIMESTAMP- oder ROWVERSION-Typ.

Parameter:

convert_int – wenn True, werden binäre Ganzzahlwerte beim Lesen in Ganzzahlen konvertiert.

Neu seit Version 1.2.

klasse sqlalchemy.dialects.mssql.TINYINT
klasse sqlalchemy.dialects.mssql.UNIQUEIDENTIFIER

Mitglieder

__init__()

methode sqlalchemy.dialects.mssql.UNIQUEIDENTIFIER.__init__(as_uuid: bool = True)

Erstellt einen UNIQUEIDENTIFIER-Typ.

Parameter:

as_uuid=True

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

klasse sqlalchemy.dialects.mssql.VARBINARY

Der MSSQL VARBINARY-Typ.

Dieser Typ fügt dem Kern-VARBINARY-Typ zusätzliche Funktionen hinzu, einschließlich des Modus „deprecate_large_types“, bei dem entweder VARBINARY(max) oder IMAGE gerendert wird, sowie der SQL Server FILESTREAM-Option.

Klassensignatur

class sqlalchemy.dialects.mssql.VARBINARY (sqlalchemy.types.VARBINARY, sqlalchemy.types.LargeBinary)

methode sqlalchemy.dialects.mssql.VARBINARY.__init__(length=None, filestream=False)

Erstellt einen VARBINARY-Typ.

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

  • filestream=False

    wenn True, rendert das FILESTREAM-Schlüsselwort in der Tabellendefinition. In diesem Fall muss length None oder 'max' sein.

    Neu in Version 1.4.31.

klasse sqlalchemy.dialects.mssql.VARCHAR

Der SQL VARCHAR-Typ.

Klassensignatur

class sqlalchemy.dialects.mssql.VARCHAR (sqlalchemy.types.String)

methode sqlalchemy.dialects.mssql.VARCHAR.__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 keine 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 ausgegeben wird, wenn eine VARCHAR ohne Länge enthalten ist. 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.mssql.XML

MSSQL XML Typ.

Dies ist ein Platzhaltertyp für Reflektionszwecke, der keine Python-seitige Datentypsupport enthält. Er unterstützt derzeit auch keine zusätzlichen Argumente wie „CONTENT“, „DOCUMENT“, „xml_schema_collection“.

Mitglieder

__init__()

methode sqlalchemy.dialects.mssql.XML.__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 keine CREATE TABLE ausgegeben wird. Bestimmte Datenbanken benötigen möglicherweise eine length für die Verwendung in DDL und lösen eine Ausnahme aus, wenn die CREATE TABLE DDL ausgegeben wird, wenn ein VARCHAR ohne Länge enthalten ist. 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.

PyODBC

Unterstützung für die Microsoft SQL Server-Datenbank über den PyODBC-Treiber.

DBAPI

Dokumentation und Download-Informationen (falls zutreffend) für PyODBC finden Sie unter: https://pypi.org/project/pyodbc/

Verbindung aufnehmen

Verbindungszeichenfolge

mssql+pyodbc://<username>:<password>@<dsnname>

Verbindung mit PyODBC aufnehmen

Die URL hier soll in PyODBC-Verbindungszeichenfolgen übersetzt werden, wie in ConnectionStrings detailliert beschrieben.

DSN-Verbindungen

Eine DSN-Verbindung in ODBC bedeutet, dass eine voreingestellte ODBC-Datenquelle auf dem Client-Computer konfiguriert ist. Die Anwendung gibt dann den Namen dieser Datenquelle an, die Details wie den verwendeten spezifischen ODBC-Treiber sowie die Netzwerkadresse der Datenbank enthält. Unter der Annahme, dass eine Datenquelle auf dem Client konfiguriert ist, sieht eine einfache DSN-basierte Verbindung wie folgt aus:

engine = create_engine("mssql+pyodbc://scott:tiger@some_dsn")

Welche oben, wird die folgende Verbindungszeichenfolge an PyODBC übergeben

DSN=some_dsn;UID=scott;PWD=tiger

Wenn der Benutzername und das Passwort weggelassen werden, fügt die DSN-Form auch die Direktive Trusted_Connection=yes zur ODBC-Zeichenfolge hinzu.

Hostname-Verbindungen

Hostname-basierte Verbindungen werden ebenfalls von pyodbc unterstützt. Diese sind oft einfacher zu verwenden als eine DSN und haben den zusätzlichen Vorteil, dass der spezifische Datenbankname, zu dem eine Verbindung hergestellt werden soll, lokal in der URL angegeben werden kann, anstatt fest als Teil einer Datenquellenkonfiguration festgelegt zu sein.

Bei Verwendung einer Hostname-Verbindung muss der Treibername auch in den Abfrageparametern der URL angegeben werden. Da diese Namen normalerweise Leerzeichen enthalten, muss der Name URL-kodiert sein, was die Verwendung von Pluszeichen für Leerzeichen bedeutet

engine = create_engine(
    "mssql+pyodbc://scott:tiger@myhost:port/databasename?driver=ODBC+Driver+17+for+SQL+Server"
)

Das Schlüsselwort driver ist für das pyodbc-Dialekt wichtig und muss klein geschrieben werden.

Alle anderen im Query-String übergebenen Namen werden in die pyodbc-Connect-Zeichenfolge übergeben, wie z. B. authentication, TrustServerCertificate usw. Mehrere Schlüsselwortargumente müssen durch ein kaufmännisches Und (&) getrennt werden; diese werden intern beim Generieren der pyodbc-Connect-Zeichenfolge in Semikolons übersetzt.

e = create_engine(
    "mssql+pyodbc://scott:tiger@mssql2017:1433/test?"
    "driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes"
    "&authentication=ActiveDirectoryIntegrated"
)

Die entsprechende URL kann mit URL konstruiert werden

from sqlalchemy.engine import URL

connection_url = URL.create(
    "mssql+pyodbc",
    username="scott",
    password="tiger",
    host="mssql2017",
    port=1433,
    database="test",
    query={
        "driver": "ODBC Driver 18 for SQL Server",
        "TrustServerCertificate": "yes",
        "authentication": "ActiveDirectoryIntegrated",
    },
)

Exakte Pyodbc-Zeichenfolge durchreichen

Eine PyODBC-Verbindungszeichenfolge kann auch im pyodbc-Format direkt übergeben werden, wie in der PyODBC-Dokumentation spezifiziert, unter Verwendung des Parameters odbc_connect. Ein URL-Objekt kann dies erleichtern

from sqlalchemy.engine import URL

connection_string = "DRIVER={SQL Server Native Client 10.0};SERVER=dagger;DATABASE=test;UID=user;PWD=password"
connection_url = URL.create(
    "mssql+pyodbc", query={"odbc_connect": connection_string}
)

engine = create_engine(connection_url)

Verbindung mit Datenbanken mit Zugriffstoken herstellen

Einige Datenbankserver sind so konfiguriert, dass sie nur Zugriffstoken für die Anmeldung akzeptieren. Beispielsweise erlaubt SQL Server die Verwendung von Azure Active Directory-Token zur Verbindung mit Datenbanken. Dies erfordert die Erstellung eines Anmeldeinformations-Objekts mithilfe der Bibliothek azure-identity. Weitere Informationen zum Authentifizierungsschritt finden Sie in der Dokumentation von Microsoft.

Nachdem eine Engine erhalten wurde, müssen die Anmeldeinformationen bei jeder angeforderten Verbindung an pyodbc.connect gesendet werden. Eine Möglichkeit, dies zu tun, besteht darin, einen Ereignis-Listener für die Engine einzurichten, der das Zugriffstoken zum Connect-Aufruf des Dialekts hinzufügt. Dies wird allgemeiner in Generieren dynamischer Authentifizierungstoken besprochen. Für SQL Server insbesondere wird dies als ODBC-Verbindungsattribut mit einer Datenstruktur übergeben, die von Microsoft beschrieben wird.

Der folgende Codeausschnitt erstellt eine Engine, die sich mit einer Azure SQL-Datenbank über Azure-Anmeldeinformationen verbindet

import struct
from sqlalchemy import create_engine, event
from sqlalchemy.engine.url import URL
from azure import identity

# Connection option for access tokens, as defined in msodbcsql.h
SQL_COPT_SS_ACCESS_TOKEN = 1256
TOKEN_URL = "https://database.windows.net/"  # The token URL for any Azure SQL database

connection_string = "mssql+pyodbc://@my-server.database.windows.net/myDb?driver=ODBC+Driver+17+for+SQL+Server"

engine = create_engine(connection_string)

azure_credentials = identity.DefaultAzureCredential()


@event.listens_for(engine, "do_connect")
def provide_token(dialect, conn_rec, cargs, cparams):
    # remove the "Trusted_Connection" parameter that SQLAlchemy adds
    cargs[0] = cargs[0].replace(";Trusted_Connection=Yes", "")

    # create token credential
    raw_token = azure_credentials.get_token(TOKEN_URL).token.encode(
        "utf-16-le"
    )
    token_struct = struct.pack(
        f"<I{len(raw_token)}s", len(raw_token), raw_token
    )

    # apply it to keyword arguments
    cparams["attrs_before"] = {SQL_COPT_SS_ACCESS_TOKEN: token_struct}

Tipp

Das Token Trusted_Connection wird derzeit vom SQLAlchemy pyodbc-Dialekt hinzugefügt, wenn kein Benutzername oder Passwort vorhanden ist. Dies muss gemäß der Dokumentation von Microsoft für Azure-Zugriffstoken entfernt werden, die besagt, dass eine Verbindungszeichenfolge bei Verwendung eines Zugriffstokens keine Parameter UID, PWD, Authentication oder Trusted_Connection enthalten darf.

Autocommit für Azure SQL Data Warehouse (DW)-Verbindungen aktivieren

Azure SQL Data Warehouse unterstützt keine Transaktionen, was zu Problemen mit dem „autobegin“ (und implizitem Commit/Rollback) Verhalten von SQLAlchemy führen kann. Wir können diese Probleme vermeiden, indem wir Autocommit sowohl auf PyODBC- als auch auf Engine-Ebene aktivieren

connection_url = sa.engine.URL.create(
    "mssql+pyodbc",
    username="scott",
    password="tiger",
    host="dw.azure.example.com",
    database="mydb",
    query={
        "driver": "ODBC Driver 17 for SQL Server",
        "autocommit": "True",
    },
)

engine = create_engine(connection_url).execution_options(
    isolation_level="AUTOCOMMIT"
)

Vermeiden des Sendens großer String-Parameter als TEXT/NTEXT

Standardmäßig senden die Microsoft ODBC-Treiber für SQL Server aus historischen Gründen lange Zeichenfolgenparameter (mehr als 4000 SBCS-Zeichen oder 2000 Unicode-Zeichen) als TEXT/NTEXT-Werte. TEXT und NTEXT sind seit vielen Jahren veraltet und verursachen Kompatibilitätsprobleme mit neueren Versionen von SQL_Server/Azure. Siehe zum Beispiel dieses Problem.

Ab ODBC Driver 18 für SQL Server können wir das Legacy-Verhalten überschreiben und lange Zeichenfolgen als varchar(max)/nvarchar(max) übergeben, indem wir den Parameter LongAsMax=Yes in der Verbindungszeichenfolge verwenden

connection_url = sa.engine.URL.create(
    "mssql+pyodbc",
    username="scott",
    password="tiger",
    host="mssqlserver.example.com",
    database="mydb",
    query={
        "driver": "ODBC Driver 18 for SQL Server",
        "LongAsMax": "Yes",
    },
)

Pyodbc Pooling / Connection Close Verhalten

PyODBC verwendet standardmäßig internes Pooling, was bedeutet, dass Verbindungen länger bestehen bleiben als innerhalb von SQLAlchemy selbst. Da SQLAlchemy sein eigenes Pooling-Verhalten hat, ist es oft vorzuziehen, dieses Verhalten zu deaktivieren. Dieses Verhalten kann nur global auf der Ebene des PyODBC-Moduls deaktiviert werden, **bevor** Verbindungen hergestellt werden

import pyodbc

pyodbc.pooling = False

# don't use the engine before pooling is set to False
engine = create_engine("mssql+pyodbc://user:pass@dsn")

Wenn diese Variable auf ihrem Standardwert von True belassen wird, **wird die Anwendung weiterhin aktive Datenbankverbindungen aufrechterhalten**, auch wenn die SQLAlchemy-Engine selbst eine Verbindung vollständig verwirft oder die Engine entsorgt wird.

Siehe auch

Pooling – in der PyODBC-Dokumentation.

Treiber / Unicode-Unterstützung

PyODBC funktioniert am besten mit Microsoft ODBC-Treibern, insbesondere im Bereich der Unicode-Unterstützung sowohl unter Python 2 als auch unter Python 3.

Die Verwendung von FreeTDS ODBC-Treibern unter Linux oder OSX mit PyODBC wird **nicht** empfohlen; es gab historisch viele Unicode-bezogene Probleme in diesem Bereich, auch bevor Microsoft ODBC-Treiber für Linux und OSX anbot. Da Microsoft nun Treiber für alle Plattformen anbietet, werden diese für die PyODBC-Unterstützung empfohlen. FreeTDS bleibt relevant für Nicht-ODBC-Treiber wie pymssql, wo es sehr gut funktioniert.

Rowcount-Unterstützung

Frühere Einschränkungen mit der „versioned rows“-Funktion des SQLAlchemy ORM mit Pyodbc wurden ab SQLAlchemy 2.0.5 behoben. Siehe die Hinweise unter Rowcount-Unterstützung / ORM-Versionierung.

Schneller Executemany-Modus

Der PyODBC-Treiber unterstützt einen „fast executemany“-Modus der Ausführung, der Rundfahrten für einen DBAPI executemany()-Aufruf bei Verwendung von Microsoft ODBC-Treibern für **begrenzte Stapelgrößen, die in den Speicher passen**, erheblich reduziert. Die Funktion wird aktiviert, indem das Attribut .fast_executemany auf dem DBAPI-Cursor gesetzt wird, wenn ein executemany-Aufruf verwendet werden soll. Das SQLAlchemy PyODBC SQL Server-Dialekt unterstützt diesen Parameter, indem der Parameter fast_executemany an create_engine() übergeben wird, **nur bei Verwendung des Microsoft ODBC-Treibers**

engine = create_engine(
    "mssql+pyodbc://scott:tiger@mssql2017:1433/test?driver=ODBC+Driver+17+for+SQL+Server",
    fast_executemany=True,
)

Geändert in Version 2.0.9: Der Parameter fast_executemany hat nun die beabsichtigte Wirkung, dass diese PyODBC-Funktion für alle INSERT-Anweisungen wirksam wird, die mit mehreren Parametersätzen ausgeführt werden und KEIN RETURNING enthalten. Zuvor würde die insertmanyvalues-Funktion von SQLAlchemy 2.0 dazu führen, dass fast_executemany in den meisten Fällen nicht verwendet wird, auch wenn es angegeben wurde.

Neu in Version 1.3.

Siehe auch

fast executemany – auf GitHub.

Setinputsizes-Unterstützung

Ab Version 2.0 wird die Methode cursor.setinputsizes() von pyodbc für alle Statement-Ausführungen verwendet, außer für cursor.executemany()-Aufrufe mit fast_executemany=True, wo sie nicht unterstützt wird (vorausgesetzt insertmanyvalues bleibt aktiviert, „fastexecutemany“ findet bei INSERT-Anweisungen ohnehin nicht statt).

Die Verwendung von cursor.setinputsizes() kann durch Übergabe von use_setinputsizes=False an create_engine() deaktiviert werden.

Wenn use_setinputsizes bei seinem Standardwert von True belassen wird, können die spezifischen per-Typ-Symbole, die an cursor.setinputsizes() übergeben werden, programmatisch über den Hook DialectEvents.do_setinputsizes() angepasst werden. Siehe diese Methode für Anwendungsbeispiele.

Geändert in Version 2.0: Das Dialekt mssql+pyodbc verwendet nun standardmäßig use_setinputsizes=True für alle Statement-Ausführungen, mit Ausnahme von cursor.executemany()-Aufrufen mit fast_executemany=True. Das Verhalten kann durch Übergabe von use_setinputsizes=False an create_engine() deaktiviert werden.

pymssql

Unterstützung für die Microsoft SQL Server-Datenbank über den pymssql-Treiber.

Verbindung aufnehmen

Verbindungszeichenfolge

mssql+pymssql://<username>:<password>@<freetds_name>/?charset=utf8

pymssql ist ein Python-Modul, das eine Python DBAPI-Schnittstelle um FreeTDS bereitstellt.

Geändert in Version 2.0.5: pymssql wurde in das kontinuierliche Integrationstest von SQLAlchemy zurückgeführt

aioodbc

Unterstützung für die Microsoft SQL Server-Datenbank über den aioodbc-Treiber.

DBAPI

Dokumentation und Download-Informationen (falls zutreffend) für aioodbc finden Sie unter: https://pypi.org/project/aioodbc/

Verbindung aufnehmen

Verbindungszeichenfolge

mssql+aioodbc://<username>:<password>@<dsnname>

Unterstützung für die SQL Server-Datenbank im asyncio-Stil, unter Verwendung des aioodbc-Treibers, der selbst ein Thread-Wrapper um pyodbc ist.

Neu in Version 2.0.23: Das Dialekt mssql+aioodbc wurde hinzugefügt, das auf der pyodbc- und der allgemeinen aio*-Dialektarchitektur aufbaut.

Durch die Verwendung einer speziellen asyncio-Mediationsschicht ist das aioodbc-Dialekt als Backend für das Paket SQLAlchemy asyncio verwendbar.

Die meisten Verhaltensweisen und Hinweise für diesen Treiber sind die gleichen wie für das pyodbc-Dialekt unter SQL Server; siehe PyODBC für allgemeine Hintergrundinformationen.

Dieses Dialekt sollte normalerweise nur mit der Engine-Erstellungsfunktion create_async_engine() verwendet werden; die Verbindungsstile sind ansonsten äquivalent zu denen, die im pyodbc-Abschnitt dokumentiert sind.

from sqlalchemy.ext.asyncio import create_async_engine

engine = create_async_engine(
    "mssql+aioodbc://scott:tiger@mssql2017:1433/test?"
    "driver=ODBC+Driver+18+for+SQL+Server&TrustServerCertificate=yes"
)