Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Der mssql-python-Treiber liefert Zeilendaten als Row Objekte aus Abrufoperationen zurück. Diese Objekte bieten flexible Zugriffsmuster:
-
Attributzugriff (
row.ColumnName) ist die lesbarste Wahl für benannte Spalten. Verwenden Sie es, wenn Ihre Abfrage eine bekannte, stabile Spaltenliste hat. -
String-Key-Zugriff (
row['ColumnName']) bietet einen wörterbuchähnlichen Zugriff auf Spalten nach Namen, was nützlich ist, wenn Sie programmatische Spaltensuche benötigen oder wenn Spaltennamen Leerzeichen oder Sonderzeichen enthalten. -
Indexzugriff (
row[0]) ist nützlich für dynamische Abfragen, bei denen Spaltennamen zur Entwicklungszeit nicht bekannt sind, oder bei der VerarbeitungSELECT *von Ergebnissen. -
Tuple-Unpacking (
a, b, c = row) ist die prägnanteste Wahl für Schleifenkörper mit einer kleinen, festen Anzahl von Spalten.
Attributzugriff
Zugriff auf Spaltenwerte direkt nach Namen:
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID = 1")
row = cursor.fetchone()
print(row.ProductID) # 1
print(row.Name) # 'Adjustable Race'
print(row.ListPrice) # 0.00
Groß- und Kleinschreibung
Der Zugriff auf den Spaltennamen ist groß- und schreibungsabhängig und entspricht den von SQL Server zurückgegebenen Spaltennamen. Wenn Ihre Datenbank inkonsistente Gehäuse verwendet, verwenden Sie SQL-Aliase AS zur Normalisierung von Namen oder aktivieren Sie die lowercase Moduleinstellung (siehe Modulkonfiguration):
cursor.execute("SELECT FirstName, LastName, EmailPromotion FROM Person.Person WHERE BusinessEntityID < 10")
row = cursor.fetchone()
print(row.FirstName) # Works
print(row.LastName) # Works
print(row.EmailPromotion) # Works
print(row.firstname) # AttributeError - wrong case
Spaltenaliase
Verwenden Sie SQL-Alias, um freundliche Attributnamen zu erstellen:
cursor.execute("""
SELECT
p.ProductID,
p.Name,
c.Name AS Category
FROM Production.Product p
JOIN Production.ProductSubcategory c ON p.ProductSubcategoryID = c.ProductSubcategoryID
WHERE p.ProductSubcategoryID IS NOT NULL
""")
for row in cursor:
print(f"{row.Name} ({row.Category})")
Indexzugriff
Zugriffswerte nach nullbasiertem Spaltenindex:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 5")
row = cursor.fetchone()
print(row[0]) # ProductID
print(row[1]) # Name
print(row[2]) # ListPrice
Negative Indexierung
Der Treiber unterstützt Python-ähnliche negative Indizierung:
cursor.execute("""
SELECT Demo.A, Demo.B, Demo.C, Demo.D
FROM (VALUES (1, 2, 3, 4)) AS Demo(A, B, C, D)
""")
row = cursor.fetchone()
print(row[-1]) # Last column (D)
print(row[-2]) # Second to last (C)
String-Key-Zugang
Greifen Sie auf Spaltenwerte nach Namen mit einer ordbuchähnlichen Syntax zu:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID = 1")
row = cursor.fetchone()
print(row['ProductID']) # 1
print(row['Name']) # 'Adjustable Race'
print(row['ListPrice']) # Decimal('0.00')
Dies ist nützlich, wenn Spaltennamen Leerzeichen oder Sonderzeichen enthalten oder wenn Sie programmatisch auf Spalten zugriffen müssen:
column_name = 'ListPrice'
value = row[column_name] # Programmatic column access
Aufteilen
Mehrere Werte mit Slices extrahieren:
cursor.execute("""
SELECT Demo.A, Demo.B, Demo.C, Demo.D, Demo.E
FROM (VALUES (1, 2, 3, 4, 5)) AS Demo(A, B, C, D, E)
""")
row = cursor.fetchone()
print(row[1:4]) # Columns B, C, D (indices 1, 2, 3)
print(row[:2]) # First two columns (A, B)
print(row[2:]) # From C to end
Tuple-Auspacken
Entpacken Sie Zeilenwerte direkt in Variablen:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 10")
for product_id, name, price in cursor:
print(f"#{product_id}: {name} - ${price}")
Teilteiliges Auspacken
Verwenden * Sie diese zur Erfassung der verbleibenden Werte:
cursor.execute("""
SELECT TOP 2 ProductID, Name, ProductNumber, Color, Size, Weight
FROM Production.Product
WHERE ProductNumber IS NOT NULL
ORDER BY ProductID
""")
for product_id, name, *rest in cursor:
print(f"{product_id}: {name}, extra columns: {rest}")
Zeilenlänge und Iteration
Arbeiten Sie mit Zeilendimensionen und iterieren Sie durch Spaltenwerte:
Erhalten Sie die Kolonnenzahl
Verwenden len() Sie, um die Anzahl der Spalten in einer Reihe zu erhalten:
cursor.execute("SELECT * FROM Production.Product WHERE ProductID < 5")
row = cursor.fetchone()
print(len(row)) # Number of columns
Iterieren Sie über Werte
Durchlaufe die Spaltenwerte in der Reihenfolge:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 5")
row = cursor.fetchone()
for value in row:
print(value)
Überprüfen Sie, ob eine Spalte existiert
Verwenden hasattr() Sie, um auf das Vorhandensein eines Spaltennamens zu testen:
# Use hasattr to check for column name
if hasattr(row, 'DiscountPrice'):
print(f"Discount: {row.DiscountPrice}")
else:
print("No discount available")
Konvertieren auf integrierte Typen
Zeilenobjekte können in Standard-Python-Typen konvertiert werden, um mit anderen Bibliotheken und APIs zu integrieren:
Konvertiere in Tupel
Konvertiere eine Zeile mit dem tuple() Konstruktor in ein Tupel:
cursor.execute("SELECT ProductID, Name FROM Production.Product WHERE ProductID = 1")
row = cursor.fetchone()
row_tuple = tuple(row)
print(row_tuple) # (1, 'Adjustable Race')
Zur Liste konvertieren
Konvertiere eine Zeile mit dem list() Konstruktor in eine Liste:
row_list = list(row)
print(row_list) # [1, 'Adjustable Race']
Zu einem Wörterbuch konvertieren
Konvertiere eine Zeile in ein Wörterbuch, wenn du sie in JSON serialisieren musst, übergebe sie an eine Template-Engine oder verschmelze sie mit anderen Daten. Baue das Wörterbuch aus und Zeilenwerten cursor.description :
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID = 1")
row = cursor.fetchone()
# Create dict from description and values
columns = [col[0] for col in cursor.description]
row_dict = dict(zip(columns, row))
print(row_dict) # {'ProductID': 1, 'Name': 'Adjustable Race', 'ListPrice': Decimal('0.00')}
Helferfunktion für die Diktierumwandlung
Erstelle eine wiederverwendbare Hilfsfunktion, um alle abgerufenen Zeilen in Wörterbücher umzuwandeln:
def rows_to_dicts(cursor):
"""Convert fetched rows to list of dictionaries."""
columns = [col[0] for col in cursor.description]
return [dict(zip(columns, row)) for row in cursor.fetchall()]
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 10")
products = rows_to_dicts(cursor)
for p in products:
print(p['Name'])
Arbeit mit nullbaren Werten
Der Treiber gibt NULL-Werte als Python Nonezurück:
cursor.execute("SELECT FirstName, MiddleName, LastName FROM Person.Person WHERE BusinessEntityID = 1")
row = cursor.fetchone()
if row.MiddleName is None:
full_name = f"{row.FirstName} {row.LastName}"
else:
full_name = f"{row.FirstName} {row.MiddleName} {row.LastName}"
Arbeit mit cursor.description
Greifen Sie auf Spaltenmetadaten neben Zeilendaten zu:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 5")
# Column information
for col in cursor.description:
print(f"Name: {col[0]}, Type: {col[1]}")
# Fetch with metadata
row = cursor.fetchone()
for i, col in enumerate(cursor.description):
print(f"{col[0]}: {row[i]}")
Allgemeine Muster
Hier sind praktische Muster für die Arbeit mit Zeilenobjekten in realen Anwendungen:
Prozesszeilen mit benanntem Zugriff
Prozesszeilen mit Attributzugriff für lesbaren, wartbaren Code:
def process_orders(conn):
cursor = conn.cursor()
cursor.execute("""
SELECT SalesOrderID, CustomerID, OrderDate, TotalDue
FROM Sales.SalesOrderHeader
WHERE Status = 5
""")
for order in cursor:
print(f"Order #{order.SalesOrderID}")
print(f" Customer: {order.CustomerID}")
print(f" Date: {order.OrderDate}")
print(f" Total: ${order.TotalDue:.2f}")
Baue Objekte aus Zeilen
Für Anwendungen mit einem Domänenmodell werden Zeilen auf Datenklassen oder typisierte Objekte abgebildet. Dieses Mapping bietet Ihnen IDE-Autovervollständigung, Typprüfung und eine klare Grenze zwischen Datenbankzeilen und Anwendungslogik.
from dataclasses import dataclass
from datetime import date
from decimal import Decimal
@dataclass
class Product:
id: int
name: str
price: Decimal
created: date
def get_products(conn) -> list[Product]:
cursor = conn.cursor()
cursor.execute("SELECT ProductID, Name, ListPrice, SellStartDate FROM Production.Product WHERE ProductID < 10")
return [
Product(
id=row.ProductID,
name=row.Name,
price=row.ListPrice,
created=row.SellStartDate
)
for row in cursor
]
Export zu JSON
Serialisiere Zeilenobjekte zu JSON mit individueller Typbehandlung für Datetime- und Dezimalwerte:
import json
from datetime import date, datetime
from decimal import Decimal
def json_serializer(obj):
"""Custom serializer for non-JSON types."""
if isinstance(obj, (date, datetime)):
return obj.isoformat()
if isinstance(obj, Decimal):
return float(obj)
raise TypeError(f"Type {type(obj)} not serializable")
def export_to_json(cursor, filename):
columns = [col[0] for col in cursor.description]
rows = [dict(zip(columns, row)) for row in cursor.fetchall()]
with open(filename, 'w') as f:
json.dump(rows, f, default=json_serializer, indent=2)
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 10")
export_to_json(cursor, "products.json")
Aggregieren in Gruppen
Gruppieren Sie Zeilen nach einem Spaltenwert und sammeln Sie sie in einem Wörterbuch zur Analyse oder Darstellung:
from collections import defaultdict
cursor.execute("""
SELECT c.Name AS CategoryName, p.Name AS ProductName, p.ListPrice
FROM Production.Product p
JOIN Production.ProductSubcategory c ON p.ProductSubcategoryID = c.ProductSubcategoryID
WHERE p.ProductSubcategoryID IS NOT NULL
ORDER BY c.Name
""")
products_by_category = defaultdict(list)
for row in cursor:
products_by_category[row.CategoryName].append({
'name': row.ProductName,
'price': row.ListPrice
})
for category, products in products_by_category.items():
print(f"\n{category}:")
for p in products:
print(f" - {p['name']}: ${p['price']}")