Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Драйвер mssql-python предлагает несколько методов извлечения, шаблоны доступа к строкам и функции навигации курсора для получения результатов запросов.
Методы поиска
После выполнения запроса SELECT используйте методы выборки для получения результатов.
fetchone()
Возвращает одну строку или None , если других строк нет:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product")
row = cursor.fetchone()
while row:
print(f"{row.ProductID}: {row.Name} - ${row.ListPrice}")
row = cursor.fetchone()
fetchmany()
Возвращает список строк.
cursor.arraysize Контролирует стандартный размер пакета (по умолчанию: 1):
cursor.execute("SELECT * FROM Production.Product")
cursor.arraysize = 100 # Fetch 100 rows at a time
while True:
rows = cursor.fetchmany()
if not rows:
break
for row in rows:
print(row.Name)
Вы также можете указать размер напрямую:
rows = cursor.fetchmany(50) # Fetch up to 50 rows
fetchall()
Возвращает все оставшиеся строки в виде списка:
cursor.execute("SELECT * FROM Production.Product WHERE Color = 'Black'")
rows = cursor.fetchall()
print(f"Found {len(rows)} products")
for row in rows:
print(row.Name)
fetchval()
Возвращает первый столбец первой строки, что полезно для скалярных запросов.
count = cursor.execute("SELECT COUNT(*) FROM Production.Product").fetchval()
print(f"Total products: {count}")
max_price = cursor.execute("SELECT MAX(ListPrice) FROM Production.Product").fetchval()
print(f"Highest price: ${max_price}")
Шаблоны доступа к строкам
Класс Row поддерживает несколько паттернов доступа.
Доступ к индексу
Доступ к столбцам по позициям (нулевый):
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 5")
row = cursor.fetchone()
product_id = row[0]
name = row[1]
price = row[2]
Доступ к атрибутам
Доступ к столбцам по названию:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 5")
row = cursor.fetchone()
product_id = row.ProductID
name = row.Name
price = row.ListPrice
Названия столбцов в нижнем регистре
Глобально включить имена атрибутов в нижнем регистре:
import mssql_python
settings = mssql_python.get_settings()
settings.lowercase = True
cursor.execute("SELECT ProductID, Name FROM Production.Product WHERE ProductID < 5")
row = cursor.fetchone()
print(row.productid, row.name) # Lowercase access
settings.lowercase = False # Restore default
Итерация
Строки поддерживают итерацию по значениям:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 5")
row = cursor.fetchone()
for value in row:
print(value)
Итерация курсора
Итерируйтесь непосредственно по курсору для обработки строк:
cursor.execute("SELECT * FROM Production.Product")
for row in cursor:
print(row.Name)
Этот паттерн эквивалентен повторяющему вызову fetchone() .
Метаданные столбца
Доступ к информации о столбце через cursor.description:
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product WHERE ProductID < 5")
for col in cursor.description:
name, type_code, display_size, internal_size, precision, scale, null_ok = col
print(f"Column: {name}, Type: {type_code}, Nullable: {null_ok}")
Число строк
Атрибут cursor.rowcount указывает:
- Для SELECT: возвращает -1 после
execute()до начала поиска. После начала извлечения отображается накопительное количество извлечённых на данный момент строк. - Для INSERT/UPDATE/DELETE: Количество затронутых строк.
cursor.execute("SELECT * FROM Production.Product")
print(f"Rows returned: {cursor.rowcount}")
cursor.execute("CREATE TABLE #PriceUpd (Name NVARCHAR(50), Price DECIMAL(10,2), CategoryID INT)")
cursor.execute("INSERT INTO #PriceUpd VALUES ('A',10,1),('B',20,1),('C',30,2)")
cursor.execute("UPDATE #PriceUpd SET Price = Price * 1.1 WHERE CategoryID = 1")
print(f"Rows updated: {cursor.rowcount}")
Навигация курсора
skip()
Пропускайте строки, не извлекая их:
cursor.execute("SELECT * FROM Production.Product ORDER BY ProductID")
cursor.skip(10) # Skip first 10 rows
row = cursor.fetchone() # Returns 11th row
scroll()
Переместите курсор вперёд:
cursor.execute("SELECT * FROM Production.Product ORDER BY ProductID")
# Move forward 5 rows from current position
cursor.scroll(5, mode='relative')
row = cursor.fetchone()
Замечание
Драйвер поддерживает только mode='relative' с положительными значениями. Абсолютное позиционирование и обратная прокрутка вызывают NotSupportedError, поскольку драйвер использует курсоры только с перемещением вперёд.
Номер строки
Отслеживайте текущее положение:
cursor.execute("SELECT * FROM Production.Product")
print(f"Initial position: {cursor.rownumber}") # -1 (before first fetch)
row = cursor.fetchone()
print(f"After fetchone: {cursor.rownumber}") # 0 (first row fetched)
Множество результирующих наборов
Используйте nextset() для обработки нескольких наборов результатов:
cursor.execute("""
SELECT * FROM Production.Product WHERE Color = 'Black';
SELECT * FROM Production.ProductCategory;
SELECT COUNT(*) FROM Production.Product;
""")
# First result set
products = cursor.fetchall()
print(f"Products: {len(products)}")
# Move to second result set
if cursor.nextset():
categories = cursor.fetchall()
print(f"Categories: {len(categories)}")
# Move to third result set
if cursor.nextset():
count = cursor.fetchval()
print(f"Total count: {count}")
Большие наборы результатов
Для больших наборов результатов обрабатывайте строки пакетами, чтобы контролировать использование памяти:
def process_batch(rows):
# Example: print each row. Replace with your own logic.
for row in rows:
print(row)
cursor.execute("SELECT * FROM LargeTable")
cursor.arraysize = 1000
while True:
rows = cursor.fetchmany()
if not rows:
break
process_batch(rows)
print(f"Processed {cursor.rownumber} rows so far")
Менеджеры контекста
Используйте менеджеры контекста для автоматической очистки ресурсов:
with mssql_python.connect(connection_string) as conn:
with conn.cursor() as cursor:
cursor.execute("SELECT * FROM Production.Product")
for row in cursor:
print(row.Name)
# Cursor and connection closed automatically
Лучшие практики
-
Используйте
fetchmany()для больших результатов , чтобы избежать загрузки всего в память. - Закройте курсоры при освобождении ресурсов сервера.
- Используйте имена столбцов (доступ к атрибутам) для более читаемого кода.
-
Проверка
rowcountпосле операторов модификации данных. -
Обрабатывайте
Noneзначения явно, когда столбцы обнулируемы.