Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
SQL NULL, eksik veya bilinmeyen verileri temsil eder. mssql-python sürücüsü, SQL NULL'u Python'a Noneeşler. Bu ayrım önemlidir çünkü NULL hiçbir şeye, kendisi de dahil olmak üzere, eşit değildir. SQL'de ise NULL = NULL NULL (bilinmiyor) olarak değerlendirilir, doğru değil, bu yüzden sorgularda ve IS NULL Python'da kullanılıris None.
NULL değerleri alın
Getirme sonuçlarında NULL
Sürücü, SQL Server'dan NULL değerleri Python Noneolarak döndürür:
import mssql_python
conn = mssql_python.connect(connection_string)
cursor = conn.cursor()
cursor.execute(
"SELECT TOP 1 FirstName, MiddleName, LastName "
"FROM Person.Person WHERE MiddleName IS NULL"
)
row = cursor.fetchone()
print(row.FirstName) # First name value
print(row.MiddleName) # None (NULL in database)
print(row.LastName) # Last name value
NULL değerleri kontrol edin
Sonuçlar arasında yinelerken, bir değerin None olup olmadığını is işleciyle denetleyin:
cursor.execute(
"SELECT FirstName, MiddleName, LastName FROM Person.Person WHERE BusinessEntityID <= 10"
)
for row in cursor:
if row.MiddleName is None:
print(f"{row.FirstName} {row.LastName}: No middle name")
else:
print(f"{row.FirstName} {row.MiddleName} {row.LastName}")
is None yerine == None kullanma
Her zaman NULL kontrolleri için kullanın is None .
is işleci özdeşliği denetler (değerin kelimenin tam anlamıyla None olup olmadığını), == ise __eq__'ü çağırır ve özel nesnelerde beklenmedik sonuçlar verebilir:
# Correct
if row.MiddleName is None:
full_name = f"{row.FirstName} {row.LastName}"
# Avoid (works but not idiomatic)
if row.MiddleName == None:
full_name = f"{row.FirstName} {row.LastName}"
NULL değerler gönder
None ile NULL ekleyin
NULL değerleri eklemek için şu noktayı geçin None:
cursor.execute(
"CREATE TABLE #NullInsertDemo "
"(Name NVARCHAR(50), Email NVARCHAR(100), Phone NVARCHAR(20))"
)
cursor.execute(
"INSERT INTO #NullInsertDemo (Name, Email, Phone) "
"VALUES (%(name)s, %(email)s, %(phone)s)",
{"name": "Alice", "email": None, "phone": "555-1234"}
)
conn.commit()
NULL olarak güncelle
Parametreleri aktararak bir sütunu NULL None olarak ayarlayın:
cursor.execute(
"CREATE TABLE #UpdateDemo (ID INT, Email NVARCHAR(100))"
)
cursor.execute("INSERT INTO #UpdateDemo VALUES (100, 'old@example.com')")
cursor.execute(
"UPDATE #UpdateDemo SET Email = %(email)s WHERE ID = %(id)s",
{"email": None, "id": 100}
)
conn.commit()
Koşullu NULL işleme
İsteğe bağlı parametreler belirtilmediğinde bunları None olarak ayarlayan işlevler tanımlayın:
def update_record(cursor, record_id: int, name: str, email: str | None = None):
"""Update record, setting email to NULL if not provided."""
cursor.execute(
"UPDATE #Records SET Name = %(name)s, Email = %(email)s "
"WHERE ID = %(id)s",
{"name": name, "email": email, "id": record_id}
)
WHERE cümlelerinde NULL
IS NULL sorgularda
NULL karşılaştırmaları için SQL'de IS NULL kullanın:
# Find people without a middle name
cursor.execute("SELECT FirstName FROM Person.Person WHERE MiddleName IS NULL")
# Find people with a middle name
cursor.execute("SELECT FirstName FROM Person.Person WHERE MiddleName IS NOT NULL")
Dinamik NULL işleme
Bir parametre NULL olabilirse, uygun sorguyu oluşturmak için koşullu mantık kullanın:
def find_people(cursor, middle_name: str | None = None):
"""Find people, optionally filtering by middle name."""
if middle_name is None:
# Find people with NULL middle name
cursor.execute("SELECT * FROM Person.Person WHERE MiddleName IS NULL")
else:
# Find people with specific middle name
cursor.execute(
"SELECT * FROM Person.Person WHERE MiddleName = %(middle_name)s",
{"middle_name": middle_name},
)
return cursor.fetchall()
NULL ikamesi için COALESCE
SQL seviyesinde varsayılan değerleri NULL yerine koymak için kullanılır COALESCE .
COALESCEPython'da kontrol None etmekten daha verimli çünkü yerine geçme sunucuda gerçekleşir ve uygulamanızdaki koşullu mantık miktarını azaltır:
cursor.execute("""
SELECT
FirstName,
COALESCE(MiddleName, '(none)') AS MiddleName,
COALESCE(Suffix, 'N/A') AS Suffix
FROM Person.Person
WHERE BusinessEntityID <= 10
""")
for row in cursor:
# MiddleName and Suffix will never be None
print(f"{row.FirstName}: {row.MiddleName}, {row.Suffix}")
NULL-güvenli işlemler
Python'da varsayılan değerler
cursor.execute("SELECT TOP 10 Name, Color FROM Production.Product")
for row in cursor:
# Use or to provide default
color = row.Color or "No color"
print(f"{row.Name}: {color}")
NULL değerleri formatla
def format_address(row):
"""Format address handling NULL components."""
parts = [
row.AddressLine1,
row.AddressLine2,
row.City,
row.PostalCode,
]
# Filter out None values
return ", ".join(str(p) for p in parts if p is not None)
cursor.execute(
"SELECT TOP 10 AddressLine1, AddressLine2, City, PostalCode "
"FROM Person.Address"
)
for row in cursor:
print(format_address(row))
Toplulaştırmalarda NULL
SQL aggregate fonksiyonları, NULL değerleri beklediğinizden farklı şekilde işliyor.
COUNT(column) yalnızca NULL olmayan değerleri sayarken COUNT(*) , tüm satırları sayar.
AVG, SUM, MIN, ve MAX hepsi NULL değerleri görmezden gelir. Sütundaki her değer NULL ise, bu fonksiyonlar NULL döndürür (sıfır değil).
# COUNT excludes NULL values
cursor.execute("SELECT COUNT(Color) FROM Production.Product") # Counts non-NULL colors
color_count = cursor.fetchval()
# COUNT(*) includes all rows
cursor.execute("SELECT COUNT(*) FROM Production.Product") # Counts all products
total_count = cursor.fetchval()
# AVG ignores NULL
cursor.execute("SELECT AVG(Weight) FROM Production.Product") # Average of non-NULL weights
average_weight = cursor.fetchval()
NULL ve veri tipleri
NULL sayısal değerler
from decimal import Decimal
cursor.execute("SELECT ListPrice FROM Production.Product WHERE ProductID = 1")
row = cursor.fetchone()
# Check before arithmetic
if row.ListPrice is not None:
tax = row.ListPrice * Decimal("0.08")
total = row.ListPrice + tax
else:
total = Decimal("0")
NULL tarih değerleri
Karşılaştırma veya hesaplamalarda kullanmadan önce bir tarih sütununun olup olmadığını None kontrol edin:
from datetime import date
cursor.execute("SELECT Name, SellEndDate FROM Production.Product WHERE ProductID <= 10")
for row in cursor:
if row.SellEndDate is None:
print(f"{row.Name}: Currently selling")
else:
print(f"{row.Name}: Discontinued on {row.SellEndDate}")
NULL dize değerleri
Birleştirmeden önce None denetleyerek NULL string sütunlarını işleyin:
cursor.execute(
"SELECT TOP 10 FirstName, MiddleName, LastName FROM Person.Person"
)
for row in cursor:
# Build full name, handling NULL middle name
if row.MiddleName:
full_name = f"{row.FirstName} {row.MiddleName} {row.LastName}"
else:
full_name = f"{row.FirstName} {row.LastName}"
print(full_name)
NULL ile toplu işlemler
NULL değerleri ile executemany
executemany() kullanırken, NULL olması gereken sütunlar için sözlüklerde None geçirin:
users = [
{"name": "Alice", "title": "Ms.", "suffix": "Jr."},
{"name": "Bob", "title": None, "suffix": "Sr."}, # NULL title
{"name": "Carol", "title": "Dr.", "suffix": None}, # NULL suffix
]
cursor.executemany(
"SELECT FirstName FROM Person.Person WHERE FirstName = %(name)s",
users
)
NULL ile toplu kopyalama
Toplu kopyalama işlemleri, veri yapılarınızdan NULL değerleri korur:
cursor = conn.cursor()
cursor.execute("CREATE TABLE ##NullDemo (Name NVARCHAR(50), Email NVARCHAR(100), Phone NVARCHAR(20))")
conn.commit()
data = [
("Alice", "alice@example.com", "555-0001"),
("Bob", None, "555-0002"), # NULL Email
("Carol", "carol@example.com", None), # NULL Phone
]
result = cursor.bulkcopy("##NullDemo", data)
conn.commit()
print(f"Copied {result['rows_copied']} rows")
Ortak desenler
Isteğe bağlı saha işleme
Satır sınıflarını veri sınıflarına eşlerken hangi alanların NULL olabileceğini netleştirmek için tip ipuçları kullanın:
from dataclasses import dataclass
from typing import Optional
@dataclass
class PersonRecord:
business_entity_id: int
first_name: str
middle_name: Optional[str] = None
suffix: Optional[str] = None
def fetch_person(cursor, person_id: int) -> Optional[PersonRecord]:
cursor.execute(
"SELECT BusinessEntityID, FirstName, MiddleName, Suffix "
"FROM Person.Person WHERE BusinessEntityID = %(id)s",
{"id": person_id},
)
row = cursor.fetchone()
if row is None:
return None
return PersonRecord(
business_entity_id=row.BusinessEntityID,
first_name=row.FirstName,
middle_name=row.MiddleName, # Will be None if NULL
suffix=row.Suffix, # Will be None if NULL
)
NULL ile JSON serileştirmesi
Python None değerleri modül kullanıldığında null otomatik olarak JSON'a json dönüştürülür:
import json
cursor.execute(
"SELECT TOP 5 BusinessEntityID, FirstName, MiddleName FROM Person.Person"
)
rows = cursor.fetchall()
# Convert to JSON-serializable list
people = []
for row in rows:
people.append({
"id": row.BusinessEntityID,
"name": row.FirstName,
"middle_name": row.MiddleName, # None becomes null in JSON
})
json_output = json.dumps(people, indent=2)
print(json_output)
# [
# {"id": 1, "name": "Ken", "middle_name": "J"},
# {"id": 3, "name": "Roberto", "middle_name": null}
# ]
NULL filtreleme ile sözlük
Satır sözlüklere dönüştürülürken NULL değerleri hariç tutmayı tercih edin:
def row_to_dict(row, cursor) -> dict:
"""Convert row to dict, optionally excluding NULL values."""
columns = [col[0] for col in cursor.description]
return {col: val for col, val in zip(columns, row) if val is not None}
cursor.execute("SELECT * FROM Person.Person WHERE BusinessEntityID = 1")
row = cursor.fetchone()
person_dict = row_to_dict(row, cursor)
# Only includes non-NULL columns
DataFrames'te NULL
Pandas veya Polars DataFrame'lerle çalışırken, bu kütüphaneler kendi sentinel değerlerini kullandığı için null değerlere ekstra dikkat etmeniz gerekir.
pandalar NaN ve NaT
pandas, NaN eksik sayısal ve dize değerleri için (Not a Number) ve NaT eksik tarih ve zaman değerleri için (Not a Time) kullanır. Her iki değer de Python Noneile aynı değildir :
import pandas as pd
import numpy as np
# When reading SQL results into pandas, NULL becomes NaN or NaT
cursor.execute("SELECT Name, Weight, SellEndDate FROM Production.Product")
table = cursor.arrow()
df = table.to_pandas()
# Check for missing values (covers NaN, NaT, and None)
print(df["Weight"].isna().sum()) # Count of NULL weights
print(df["SellEndDate"].isna().sum()) # Count of NULL dates
# Stage the data in a temp table to avoid mutating the source table
cursor.execute("CREATE TABLE #ProductWeights (Name NVARCHAR(100), Weight DECIMAL(8, 2) NULL)")
# Convert NaN back to None so NULL values round-trip correctly
for _, row in df.iterrows():
weight = None if pd.isna(row["Weight"]) else float(row["Weight"])
cursor.execute(
"INSERT INTO #ProductWeights (Name, Weight) VALUES (%(name)s, %(weight)s)",
{"name": row["Name"], "weight": weight}
)
Warning
== np.nan veya == pd.NaT ile karşılaştırmayın. Bu karşılaştırmalar her zaman False döndürür. Bunun yerine pd.isna() veya pd.notna() kullanın.
Polars boş değer işleme
Polars, doğrudan Python None ile eşlenen kendi null değerini (NaN değil) kullanır:
import polars as pl
cursor.execute("SELECT Name, Weight, Color FROM Production.Product")
table = cursor.arrow()
df = pl.from_arrow(table)
# Filter rows with non-null values
has_weight = df.filter(pl.col("Weight").is_not_null())
# Replace null with a default
df = df.with_columns(pl.col("Color").fill_null("No color"))