SQLAlchemy 2.0 Dokumentation
Dialekte
- PostgreSQL
- MySQL und MariaDB
- SQLite
- Oracle
- Microsoft SQL Server¶
- Unterstützung für die Microsoft SQL Server-Datenbank.
- Externe Dialekte
- Auto-Inkrement-Verhalten / IDENTITY-Spalten
- SEQUENCE-Unterstützung
- MAX bei VARCHAR / NVARCHAR
- Collation-Unterstützung
- LIMIT/OFFSET-Unterstützung
- DDL-Kommentar-Unterstützung
- Transaktionsisolationslevel
- Temporäre Tabellen / Ressourcenrücksetzung für Connection Pooling
- Nullbarkeit
- Datums- / Zeitbehandlung
- Veraltung großer Text-/Binärtypen
- Mehrteilige Schemanamen
- Legacy-Schema-Modus
- Clustered Index-Unterstützung
- Columnstore Index-Unterstützung
- MSSQL-spezifische Indexoptionen
- Kompatibilitätsstufen
- Trigger
- Zeilenanzahl-Unterstützung / ORM-Versioning
- Snapshot-Isolation aktivieren
- SQL Server SQL-Konstrukte
- SQL Server-Datentypen
- PyODBC
- DBAPI
- Verbinden
- Verbindung mit PyODBC
- DSN-Verbindungen
- Hostname-Verbindungen
- Genaue Pyodbc-Zeichenfolge übergeben
- Verbindung mit Datenbanken mit Zugriffstoken
- Vermeidung von transaktionsbezogenen Ausnahmen bei Azure Synapse Analytics
- Automatische Bestätigung für Azure SQL Data Warehouse (DW)-Verbindungen aktivieren
- Vermeidung des Sendens großer Zeichenkettenparameter als TEXT/NTEXT
- Pyodbc Pooling / Verhalten beim Schließen der Verbindung
- Treiber / Unicode-Unterstützung
- Zeilenanzahl-Unterstützung
- Schneller Executemany-Modus
- Setinputsizes-Unterstützung
- pymssql
- aioodbc
Projektversionen
- Vorher: Oracle
- Nächste: Häufig gestellte Fragen
- Nach oben: Startseite
- Auf dieser Seite
- Microsoft SQL Server
- Unterstützung für die Microsoft SQL Server-Datenbank.
- Externe Dialekte
- Auto-Inkrement-Verhalten / IDENTITY-Spalten
- SEQUENCE-Unterstützung
- MAX bei VARCHAR / NVARCHAR
- Collation-Unterstützung
- LIMIT/OFFSET-Unterstützung
- DDL-Kommentar-Unterstützung
- Transaktionsisolationslevel
- Temporäre Tabellen / Ressourcenrücksetzung für Connection Pooling
- Nullbarkeit
- Datums- / Zeitbehandlung
- Veraltung großer Text-/Binärtypen
- Mehrteilige Schemanamen
- Legacy-Schema-Modus
- Clustered Index-Unterstützung
- Columnstore Index-Unterstützung
- MSSQL-spezifische Indexoptionen
- Kompatibilitätsstufen
- Trigger
- Zeilenanzahl-Unterstützung / ORM-Versioning
- Snapshot-Isolation aktivieren
- SQL Server SQL-Konstrukte
- SQL Server-Datentypen
- PyODBC
- DBAPI
- Verbinden
- Verbindung mit PyODBC
- DSN-Verbindungen
- Hostname-Verbindungen
- Genaue Pyodbc-Zeichenfolge übergeben
- Verbindung mit Datenbanken mit Zugriffstoken
- Vermeidung von transaktionsbezogenen Ausnahmen bei Azure Synapse Analytics
- Automatische Bestätigung für Azure SQL Data Warehouse (DW)-Verbindungen aktivieren
- Vermeidung des Sendens großer Zeichenkettenparameter als TEXT/NTEXT
- Pyodbc Pooling / Verhalten beim Schließen der Verbindung
- Treiber / Unicode-Unterstützung
- Zeilenanzahl-Unterstützung
- Schneller Executemany-Modus
- Setinputsizes-Unterstützung
- pymssql
- aioodbc
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.
Support-Typ |
Versionen |
|---|---|
2012+ |
|
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=Falsedeaktiviert wurde, werden entweder die Funktionscope_identity()oder die Variable@@identityverwendet; 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 lastrowidnach einer INSERT-Anweisung auf. Wenn das Flaguse_scope_identity=Falseancreate_engine()übergeben wird, wird stattdessen die AnweisungSELECT @@identity AS lastrowidverwendet.
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
COMMITDies 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 NULLLIMIT/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 tableFü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_1Beachten 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-spezifischREAD COMMITTEDREAD UNCOMMITTEDREPEATABLE READSERIALIZABLESNAPSHOT- 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) NULLWenn 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
Trueist, rendern die DatentypenUnicodeText,TextClauseundLargeBinarybeim Rendern von DDL die TypenNVARCHAR(max),VARCHAR(max)bzw.VARBINARY(max). Dies ist ein neues Verhalten ab der Einführung dieses Flags.Wenn dieses Flag
Falseist, rendern die DatentypenUnicodeText,TextClauseundLargeBinarybeim Rendern von DDL die TypenNTEXT,TEXTbzw.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 wieFalse.Bei der ersten Verbindung erkennt der Dialekt, ob SQL Server Version 2012 oder neuer verwendet wird. Wenn das Flag immer noch
Noneist, wird es aufTrueoderFalsegesetzt, je nachdem, ob 2012 oder neuer erkannt wurde.Das Flag kann beim Erstellen des Dialekts entweder auf
TrueoderFalsegesetzt werden, typischerweise übercreate_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,IMAGEbleiben 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
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 ONHintergrundinformationen 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 |
- 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 einCAST, 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
CompileErroraus, 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 vonsqlalchemy.als auch vonsqlalchemy.dialects.mssqlimportierbar.try_cast()gibt eine Instanz vonTryCastzurück und verhält sich im Allgemeinen ähnlich wie dasCast-Konstrukt; auf SQL-Ebene ist der Unterschied zwischenCASTundTRY_CAST, dassTRY_CASTNULL 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 |
|---|---|
MSSQL BIT Typ. |
|
Der SQL-Datentyp DOUBLE PRECISION. |
|
MSSQL JSON Typ. |
|
MSSQL NTEXT Typ, für Unicode-Text mit variabler Länge bis zu 2^30 Zeichen. |
|
Der SQL-Datentyp REAL. |
|
Implementiert den SQL Server ROWVERSION Typ. |
|
Implementiert den SQL Server TIMESTAMP Typ. |
|
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
Klassensignatur
class
sqlalchemy.dialects.mssql.BIT(sqlalchemy.types.Boolean)-
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 vonBooleanKonstruiert 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.nameoder 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.
-
method
- 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 vonStringErstellt 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 TABLEwill be issued. Certain databases may require alengthfor use in DDL, and will raise an exception when theCREATE TABLEDDL is issued if aVARCHARwith 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_1Hinweis
In den meisten Fällen sollten die Datentypen
UnicodeoderUnicodeTextfür eineColumnverwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.
-
method
- 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.
Klassensignatur
class
sqlalchemy.dialects.mssql.DOUBLE_PRECISION(sqlalchemy.types.DOUBLE_PRECISION)
- class sqlalchemy.dialects.mssql.IMAGE¶
Mitglieder
Klassensignatur
class
sqlalchemy.dialects.mssql.IMAGE(sqlalchemy.types.LargeBinary)-
method
sqlalchemy.dialects.mssql.IMAGE.__init__(length: int | None = None)¶ geerbt von der
sqlalchemy.types.LargeBinary.__init__Methode vonLargeBinaryKonstruiert 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.
-
method
- 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 alsNVARCHAR(max)dargestellt, bietet jedoch JSON-Vergleichsfunktionen sowie Python-Koerzierungsverhalten.JSONwird 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 vonJSONbereitgestellt werden, indem die Operationen an dieJSON_VALUE- oderJSON_QUERY-Funktionen auf Datenbankebene angepasst werden.Der SQL Server
JSON-Typ verwendet notwendigerweise die FunktionenJSON_QUERYundJSON_VALUEbei 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 FunktionJSON_QUERYgibt **nur** ein JSON-Dictionary oder eine Liste zurück, aber kein einzelnes String-, numerisches oder boolesches Element; die FunktionJSON_VALUEgibt **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:
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"} )
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
Klassensignatur
class
sqlalchemy.dialects.mssql.JSON(sqlalchemy.types.JSON)-
methode
sqlalchemy.dialects.mssql.JSON.__init__(none_as_null: bool = False)¶ geerbt von der
sqlalchemy.types.JSON.__init__Methode vonJSONErstellt einen
JSON-Typ.- Parameter:
none_as_null=False¶ –
wenn True, wird der Wert
Noneals SQL NULL-Wert gespeichert, nicht als JSON-Kodierung vonnull. Beachten Sie, dass, wenn dieses Flag False ist, dernull()-Konstrukt immer noch verwendet werden kann, um einen NULL-Wert zu speichern, der direkt als Parameterwert übergeben werden kann und vomJSON-Typ speziell als SQL NULL interpretiert wird.from sqlalchemy import null conn.execute(table.insert(), {"data": null()})
Hinweis
JSON.none_as_nullgilt nicht für die anColumn.defaultundColumn.server_defaultübergebenen Werte; ein für diese Parameter übergebener Wert vonNonebedeutet „kein Standardwert vorhanden“.Zusätzlich gilt bei Verwendung in SQL-Vergleichsausdrücken der Python-Wert
Noneweiterhin für SQL null und nicht für JSON NULL. Das FlagJSON.none_as_nullbezieht sich explizit auf die Speicherung des Werts in einer INSERT- oder UPDATE-Anweisung. Der WertJSON.NULLsollte für SQL-Ausdrücke verwendet werden, die mit JSON null verglichen werden sollen.Siehe auch
- klasse sqlalchemy.dialects.mssql.MONEY¶
Klassensignatur
class
sqlalchemy.dialects.mssql.MONEY(sqlalchemy.types.TypeEngine)
- 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 vonStringErstellt 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 TABLEausgegeben wird. Bestimmte Datenbanken erfordern möglicherweise einelengthfür die Verwendung in DDL und lösen eine Ausnahme aus, wenn dieCREATE TABLEDDL ausgegeben wird, wenn eineVARCHARohne 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_1Hinweis
In den meisten Fällen sollten die Datentypen
UnicodeoderUnicodeTextfür eineColumnverwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.
-
methode
- klasse sqlalchemy.dialects.mssql.NTEXT¶
MSSQL NTEXT Typ, für Unicode-Text mit variabler Länge bis zu 2^30 Zeichen.
Mitglieder
Klassensignatur
class
sqlalchemy.dialects.mssql.NTEXT(sqlalchemy.types.UnicodeText)-
methode
sqlalchemy.dialects.mssql.NTEXT.__init__(length: int | None = None, collation: str | None = None)¶ geerbt von der
sqlalchemy.types.String.__init__Methode vonStringErstellt 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 TABLEausgegeben wird. Bestimmte Datenbanken erfordern möglicherweise einelengthfür die Verwendung in DDL und lösen eine Ausnahme aus, wenn dieCREATE TABLEDDL ausgegeben wird, wenn eineVARCHARohne 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_1Hinweis
In den meisten Fällen sollten die Datentypen
UnicodeoderUnicodeTextfür eineColumnverwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.
-
methode
- 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 vonStringErstellt 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 TABLEausgegeben wird. Bestimmte Datenbanken erfordern möglicherweise einelengthfür die Verwendung in DDL und lösen eine Ausnahme aus, wenn dieCREATE TABLEDDL ausgegeben wird, wenn eineVARCHARohne 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_1Hinweis
In den meisten Fällen sollten die Datentypen
UnicodeoderUnicodeTextfür eineColumnverwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.
-
methode
- klasse sqlalchemy.dialects.mssql.REAL¶
Der SQL-Datentyp REAL.
Klassensignatur
class
sqlalchemy.dialects.mssql.REAL(sqlalchemy.types.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
Mitglieder
Klassensignatur
class
sqlalchemy.dialects.mssql.ROWVERSION(sqlalchemy.dialects.mssql.base.TIMESTAMP)-
methode
sqlalchemy.dialects.mssql.ROWVERSION.__init__(convert_int=False)¶ geerbt von der
sqlalchemy.dialects.mssql.base.TIMESTAMP.__init__Methode vonTIMESTAMPErstellt einen TIMESTAMP- oder ROWVERSION-Typ.
- Parameter:
convert_int¶ – wenn True, werden binäre Ganzzahlwerte beim Lesen in Ganzzahlen konvertiert.
Neu seit Version 1.2.
-
methode
- klasse sqlalchemy.dialects.mssql.SMALLDATETIME¶
Mitglieder
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 vonDateTimeErstellt 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.
-
methode
- klasse sqlalchemy.dialects.mssql.SMALLMONEY¶
Klassensignatur
class
sqlalchemy.dialects.mssql.SMALLMONEY(sqlalchemy.types.TypeEngine)
- klasse sqlalchemy.dialects.mssql.SQL_VARIANT¶
Klassensignatur
class
sqlalchemy.dialects.mssql.SQL_VARIANT(sqlalchemy.types.TypeEngine)
- 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 vonStringErstellt 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 TABLEausgegeben wird. Bestimmte Datenbanken erfordern möglicherweise einelengthfür die Verwendung in DDL und lösen eine Ausnahme aus, wenn dieCREATE TABLEDDL ausgegeben wird, wenn eineVARCHARohne 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_1Hinweis
In den meisten Fällen sollten die Datentypen
UnicodeoderUnicodeTextfür eineColumnverwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.
-
methode
- klasse sqlalchemy.dialects.mssql.TIME¶
Klassensignatur
class
sqlalchemy.dialects.mssql.TIME(sqlalchemy.types.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
Mitglieder
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.
-
methode
- klasse sqlalchemy.dialects.mssql.TINYINT¶
Klassensignatur
class
sqlalchemy.dialects.mssql.TINYINT(sqlalchemy.types.Integer)
- klasse sqlalchemy.dialects.mssql.UNIQUEIDENTIFIER¶
Mitglieder
Klassensignatur
class
sqlalchemy.dialects.mssql.UNIQUEIDENTIFIER(sqlalchemy.types.Uuid)-
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.
-
methode
- 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 entwederVARBINARY(max)oder IMAGE gerendert wird, sowie der SQL ServerFILESTREAM-Option.Siehe auch
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 musslengthNoneoder'max'sein.Neu in Version 1.4.31.
-
methode
- 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 vonStringErstellt 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 TABLEausgegeben wird. Bestimmte Datenbanken erfordern möglicherweise einelengthfür die Verwendung in DDL und lösen eine Ausnahme aus, wenn dieCREATE TABLEDDL ausgegeben wird, wenn eineVARCHARohne 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_1Hinweis
In den meisten Fällen sollten die Datentypen
UnicodeoderUnicodeTextfür eineColumnverwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.
-
methode
- 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
Klassensignatur
-
methode
sqlalchemy.dialects.mssql.XML.__init__(length: int | None = None, collation: str | None = None)¶ geerbt von der
sqlalchemy.types.String.__init__Methode vonStringErstellt 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 TABLEausgegeben wird. Bestimmte Datenbanken benötigen möglicherweise einelengthfür die Verwendung in DDL und lösen eine Ausnahme aus, wenn dieCREATE TABLEDDL ausgegeben wird, wenn einVARCHARohne 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_1Hinweis
In den meisten Fällen sollten die Datentypen
UnicodeoderUnicodeTextfür eineColumnverwendet werden, die nicht-ASCII-Daten speichern soll. Diese Datentypen stellen sicher, dass die korrekten Typen in der Datenbank verwendet werden.
-
methode
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=tigerWenn 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.
Vermeidung von Transaktionsfehlern bei Azure Synapse Analytics¶
Azure Synapse Analytics unterscheidet sich erheblich in der Transaktionsbehandlung von einfachem SQL Server; in einigen Fällen kann ein Fehler innerhalb einer Synapse-Transaktion dazu führen, dass diese serverseitig willkürlich beendet wird, was wiederum dazu führt, dass die DBAPI-Methode .rollback() (sowie .commit()) fehlschlägt. Das Problem verhindert den üblichen DBAPI-Vertrag, der es erlaubt, .rollback() stillschweigend zu bestehen, wenn keine Transaktion vorhanden ist, da der Treiber diese Bedingung nicht erwartet. Das Symptom dieses Fehlers ist eine Ausnahme mit einer Meldung wie „Keine entsprechende Transaktion gefunden. (111214)“, wenn versucht wird, ein .rollback() nach einem Fehler einer Operation auszugeben.
Dieser spezielle Fall kann durch Übergabe von ignore_no_transaction_on_rollback=True an das SQL Server-Dialekt über die Funktion create_engine() wie folgt behandelt werden
engine = create_engine(
connection_url, ignore_no_transaction_on_rollback=True
)Mit dem obigen Parameter fängt das Dialekt ProgrammingError-Ausnahmen ab, die während connection.rollback() ausgelöst werden, und gibt eine Warnung aus, wenn die Fehlermeldung den Code 111214 enthält, löst jedoch keine Ausnahme aus.
Neu in Version 1.4.40: Der Parameter ignore_no_transaction_on_rollback=True wurde hinzugefügt.
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=utf8pymssql 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"
)Die Designs von flambé! dem Drachen und Der Alchemist wurden von Rotem Yaari erstellt und großzügig gespendet.
Erstellt mit Sphinx 7.2.6. Dokumentation zuletzt generiert: Di 11 Mär 2025 14:40:17 EDT