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.
DuckDB, veri kopyalamadan Apache Arrow tablolarını doğrudan sorgulayabilen süreçte çalışan bir SQL analiz motorudur. DuckDB'yi mssql-python sürücüsü ile birleştirmek şunları sağlar:
- Microsoft SQL sonuç kümelerinde verileri pandas veya Polars'a yüklemeden analitik SQL sorguları çalıştırın.
- Bellekteki Arrow tablolarını sıfır kopyalama ek yükü olmadan sorgulayın.
- Microsoft SQL verilerini yerel dosyalarla (CSV, Parquet, JSON) tek bir DuckDB sorgusunda birleştirin.
- Microsoft SQL verilerini DuckDB üzerinden Parquet, CSV veya diğer formatlara aktarın.
Prerequisites
- Python 3.10 veya üzeri.
-
mssql-python,duckdbvepyarrowpaketleri. Tümünüpip install mssql-python duckdb pyarrowile yükleyin. - Tek seferlik işletim sistemine özgü önkoşulları yükleyin. Windows kullanıcıları bu adımı atlayabilir. Platformun tam detayları için mssql-python'u Install sayfasına bakınız.
SQL veritabanı oluşturma
Aşağıdaki platformlardan birinde bir SQL veritabanı oluşturun veya bağlanın:
Bu makaledeki örnekler örnek veritabanını AdventureWorks sorgulamaktadır. Henüz sahip değilseniz, AdventureWorks örnek veritabanlarına bakabilirsiniz.
Bağımlılıkları yükleme
pip install mssql-python duckdb pyarrow
DuckDB ile Microsoft SQL verilerini sorgulama
Temel iş akışı şudur: mssql-python ile bir sorgu çalıştırın, sonuçları bir Ok tablosu olarak alın, ardından o Ok tablosunu DuckDB SQL ile sorgulayın.
Temel desen
Bir bağlantı kurup verileri bir Ok tablosu olarak getirerek başlayın.
import duckdb
import mssql_python
conn = mssql_python.connect(
"Server=<server>.database.windows.net;"
"Database=<database>;"
"Authentication=ActiveDirectoryDefault;"
"Encrypt=yes"
)
cursor = conn.cursor()
# Fetch Microsoft SQL data as Arrow
cursor.execute("SELECT * FROM Production.Product WHERE ListPrice > 0")
products = cursor.arrow()
# Query the Arrow table with DuckDB
result = duckdb.sql("""
SELECT Color, COUNT(*) AS ProductCount, AVG(ListPrice) AS AvgPrice
FROM products
GROUP BY Color
ORDER BY ProductCount DESC
""")
print(result.fetchdf())
DuckDB, Arrow tablosuna products Python değişken adıyla atıfta bulunur. DuckDB'nin depolama alanına hiçbir veri kopyalanmaz.
Agregat ve filtre
DuckDB'nin SQL'ini kullanarak Arrow verilerini gruplayın ve birleştirin.
cursor.execute("SELECT * FROM Sales.SalesOrderHeader")
orders = cursor.arrow()
# Top customers by total spend
top_customers = duckdb.sql("""
SELECT
CustomerID,
COUNT(*) AS OrderCount,
SUM(TotalDue) AS TotalSpent,
AVG(TotalDue) AS AvgOrderValue
FROM orders
GROUP BY CustomerID
HAVING SUM(TotalDue) > 10000
ORDER BY TotalSpent DESC
LIMIT 20
""")
print(top_customers.fetchdf())
Birden fazla Microsoft SQL sonucuna katıl
Microsoft SQL'den birden fazla tablo getirin ve bunları DuckDB'ye katlayın, sunucular arası sorgu yazmadan.
# Fetch two tables
cursor.execute("SELECT * FROM Production.Product")
products = cursor.arrow()
cursor.execute("SELECT * FROM Production.ProductSubcategory")
subcategories = cursor.arrow()
# Join in DuckDB
result = duckdb.sql("""
SELECT
s.Name AS Subcategory,
COUNT(*) AS ProductCount,
ROUND(AVG(p.ListPrice), 2) AS AvgPrice
FROM products p
JOIN subcategories s ON p.ProductSubcategoryID = s.ProductSubcategoryID
GROUP BY s.Name
ORDER BY AvgPrice DESC
""")
print(result.fetchdf())
Microsoft SQL verilerini yerel dosyalarla birleştir
DuckDB, CSV, Parquet ve JSON dosyalarını doğal olarak okuyabilir. SQL Server verilerini yerel dosyalarla tek bir sorguda birleştirin.
CSV dosyası ile birleştirin
Bir CSV dosyası yükleyin ve Microsoft SQL'den gelen verilerle birleştirin.
import csv
from pathlib import Path
cursor.execute("SELECT CustomerID, PersonID FROM Sales.Customer")
customers = cursor.arrow()
csv_path = Path("customer_regions.csv")
with csv_path.open("w", newline="", encoding="utf-8") as file:
writer = csv.writer(file)
writer.writerow(["CustomerID", "Region", "Segment"])
writer.writerows([
(1, "West", "Premium"),
(2, "East", "Standard"),
(3, "Central", "Basic"),
])
try:
result = duckdb.sql("""
SELECT c.CustomerID, c.PersonID, f.Region, f.Segment
FROM customers c
JOIN read_csv_auto('customer_regions.csv') f ON c.CustomerID = f.CustomerID
""")
print(result.fetchdf())
finally:
csv_path.unlink(missing_ok=True)
Parquet dosyası ile birleştirme
Bir Parquet dosyası yükleyin ve Microsoft SQL'den gelen verilerle birleştirin.
from pathlib import Path
import pyarrow as pa
import pyarrow.parquet as pq
cursor.execute("SELECT ProductID, Name, ListPrice FROM Production.Product")
products = cursor.arrow()
parquet_path = Path("order_history.parquet")
order_history = pa.table({
"ProductID": [1, 2, 680],
"OrderDate": ["2024-06-01", "2024-03-15", "2024-01-10"],
"Quantity": [10, 5, 3],
})
pq.write_table(order_history, parquet_path)
try:
result = duckdb.sql("""
SELECT p.Name, p.ListPrice, h.OrderDate, h.Quantity
FROM products p
JOIN read_parquet('order_history.parquet') h ON p.ProductID = h.ProductID
WHERE h.OrderDate >= '2024-01-01'
""")
print(result.fetchdf())
finally:
parquet_path.unlink(missing_ok=True)
Microsoft SQL verilerini eksport et
DuckDB'COPYnin ifadesini kullanarak Microsoft SQL verilerini çeşitli dosya formatlarına aktarın.
Parquet olarak dışa aktar
Verileri Apache Parquet formatına aktarın.
cursor.execute("SELECT * FROM Production.Product")
products = cursor.arrow()
duckdb.sql("COPY products TO 'products.parquet' (FORMAT PARQUET)")
CSV’ye aktar
Veriyi virgülle ayrılmış bir değerler dosyasına aktarın:
cursor.execute("SELECT * FROM Sales.SalesOrderHeader")
orders = cursor.arrow()
duckdb.sql("COPY orders TO 'orders.csv' (FORMAT CSV, HEADER)")
Bölümlenmiş Parquet'i dışa aktar
Dağıtık analitik için verileri bölümlenmiş Parquet dosyalarına aktarın:
import shutil
from pathlib import Path
cursor.execute("SELECT * FROM Sales.SalesOrderHeader")
orders = cursor.arrow()
output_dir = Path("sales_data")
shutil.rmtree(output_dir, ignore_errors=True)
duckdb.sql("""
COPY (SELECT *, YEAR(OrderDate) AS OrderYear FROM orders)
TO 'sales_data'
(FORMAT PARQUET, PARTITION_BY (OrderYear))
""")
Büyük sonuç kümelerini akışla
Büyük veri setleri için, tüm satırları aynı anda belleğe yüklemeden akış gruplarında veri işlemek için kullanılır arrow_reader() :
cursor.execute("SELECT * FROM Production.TransactionHistory")
reader = cursor.arrow_reader(batch_size=50000)
# Process each batch with DuckDB
total_rows = 0
for batch in reader:
result = duckdb.sql("""
SELECT ProductID, SUM(ActualCost) AS TotalCost
FROM batch
GROUP BY ProductID
""")
total_rows += batch.num_rows
print(f"Processed {total_rows} rows")
Yayın sonuçları biriktirin
Tüm partiler arasında toplamak için, her partiyi kalıcı bir DuckDB bağlantısına kaydedin ve sonuçları kademeli olarak biriktirin.
cursor.execute("SELECT * FROM Production.TransactionHistory")
reader = cursor.arrow_reader(batch_size=50000)
duck = duckdb.connect()
duck.execute("CREATE TABLE transactions (ProductID INT, ActualCost DOUBLE, Quantity INT)")
for batch in reader:
duck.execute("INSERT INTO transactions SELECT ProductID, ActualCost, Quantity FROM batch")
# Query the accumulated data
result = duck.sql("""
SELECT ProductID, SUM(ActualCost) AS TotalCost, SUM(Quantity) AS TotalQty
FROM transactions
GROUP BY ProductID
ORDER BY TotalCost DESC
LIMIT 10
""")
print(result.fetchdf())
duck.close()
Performans ipuçları
Bırakın Microsoft SQL ağır işleri üstlensin
Microsoft SQL, filtreleme, birleştirme ve toplama işlemlerinde, tüm ham verileri kablo üzerinden çekmekten daha hızlıdır. DuckDB'yi, zaten alınmış sonuç kümelerinde ikincil analiz için kullanın, SQL Server sorgu optimizasyonunun yerine değil.
# Suboptimal: Pull all rows, filter in DuckDB
cursor.execute("SELECT * FROM Sales.SalesOrderHeader")
orders = cursor.arrow()
result = duckdb.sql("SELECT * FROM orders WHERE TotalDue > 1000")
# Better: Filter in Microsoft SQL, analyze in DuckDB
cursor.execute("SELECT * FROM Sales.SalesOrderHeader WHERE TotalDue > 1000")
orders = cursor.arrow()
result = duckdb.sql("SELECT CustomerID, SUM(TotalDue) FROM orders GROUP BY CustomerID")
Tüm okuma işlemleri için Arrow kullanın
Ok tabanlı transfer, ara Python nesneleri oluşturmayı engeller; bu da bellek kullanımını azaltır ve veri verimliliğini artırır. DuckDB'ye veri aktarırken manuel satır satır dönüştürme yerine cursor.arrow() tercih edin.
Büyük veri kümeleri için akış kullanın
Kullanılabilir belleği aşan sonuç kümeleri için, verileri artımlı olarak işlemek üzere batch_size parametresiyle arrow_reader() kullanın.