Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Драйвер 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значения явно, когда столбцы обнулируемы.