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.
SQLAlchemy, en yaygın kullanılan Python ORM ve veritabanı araç setidir. SQLAlchemy 2.1.0b2 ile başlayarak, mssql-python sürücüsü için yerleşik bir lehçe sayesinde SQLAlchemy ORM ve Core ile Microsoft SQL ve Azure SQL Veritabanı ile kullanılabiliyor.
Important
mssql-python lehçesi, SQLAlchemy 2.1.0b2'de eklendi (16 Nisan 2026'da yayımlandı). SQLAlchemy 2.1 şu anda ön sürüm serisidir ve üretim kullanımı için önerilmez. SQLAlchemy 2.0'dan yükseltme yapmadan önce şunu anlayın:
- API'ler, nihai stabil sürümden (2.1 GA) önce değişebilir.
- Görevden önce iş yükünüzü iyice test edin
- 2.1 GA seviyesine ulaşana kadar üretim sistemleri için stabil SQLAlchemy 2.0.x kullanın
-
Bağımlılığınızı belirli bir sürüme (örneğin,
sqlalchemy==2.1.0b2) sabitleyin, sürüm aralıkları kullanmak yerine
Ön sürüm sürümlerinin ne zaman kullanılacağına dair detaylar için Bilinen Sınırlamalar bölümüne bakınız.
Prerequisites
- Python 3.10 veya üzeri. SQLAlchemy 2.1, Python 3.9 ve daha önceki sürümleri desteklemeyi bıraktı.
- ve
mssql-pythonsqlalchemypaketleri (2.1.0b2 veya daha sonra).
Bu makaledeki örnekler AdventureWorksLT örnek veritabanını kullanır. Eğer AdventureWorksLT'niz yüklü değilse, AdventureWorks örnek veritabanlarına bakabilirsiniz.
Ön sürümü kur
SQLAlchemy 2.1 beta sürümünde olduğu için pip install sqlalchemy varsayılan olarak en son kararlı 2.0.x sürümünü yükler. Ön sürümü açıkça kurun:
pip install mssql-python "sqlalchemy>=2.1.0b2"
Yüklü sürümü doğrulayın:
import sqlalchemy
print(sqlalchemy.__version__) # Should show 2.1.0b2 or later
Bağlantı URL'leri
mssql-python lehçesi URL şeması olarak kullanır mssql+mssqlpython . Genel biçim:
mssql+mssqlpython://<username>:<password>@<host>:<port>/<database>
SQL kimlik doğrulaması
SQL kimlik doğrulaması için, bağlantı URL'sine kullanıcı adı ve şifreyi ekleyin:
from sqlalchemy import create_engine
# Replace <password> with your actual password. Avoid using the sa account in production.
engine = create_engine(
"mssql+mssqlpython://dbuser:<password>@localhost:1433/<database>"
)
Microsoft Entra kimlik doğrulama
Microsoft Entra kimlik doğrulaması için boş bir kullanıcı adı ve authentication sorgu parametresi kullanın:
from sqlalchemy import create_engine
engine = create_engine(
"mssql+mssqlpython://@<server>.database.windows.net/<database>"
"?authentication=ActiveDirectoryDefault&encrypt=yes"
)
Note
ActiveDirectoryDefault
DefaultAzureCredential, kullanır ve bu da birden fazla kimlik doğrulama sağlayıcısını sırayla dener. İlk bağlantı yavaş olabilir çünkü SDK çalışan bir sağlayıcı bulana kadar zincirde yürür. Üretimde, ortamınızın hangi kimlik bilgisi türünü kullandığını biliyorsanız, zincirde dolaşmayı önlemek için bunu doğrudan belirtin (örneğin, yönetilen kimlik için ActiveDirectoryMSI). Daha fazla bilgi için bkz . Microsoft Entra kimlik doğrulaması.
URL'leri programatik olarak oluştur
Manuel URL kodlamasından kaçınmak için kullanın sqlalchemy.engine.URL.create :
from sqlalchemy.engine import URL
url = URL.create(
"mssql+mssqlpython",
username="dbuser",
password="<password>",
host="localhost",
port=1433,
database="<database>",
)
engine = create_engine(url)
ORM modellerini tanımlayın
Microsoft SQL tablolarına eşleyen modelleri tanımlamak için SQLAlchemy'nin bildirmesel eşlemesini kullanın.
from datetime import datetime
from decimal import Decimal
from sqlalchemy import Identity, String, Numeric, Integer, DateTime, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class Product(Base):
__tablename__ = "Product"
__table_args__ = {"schema": "SalesLT"}
product_id: Mapped[int] = mapped_column(
"ProductID", Integer, Identity(), primary_key=True
)
name: Mapped[str] = mapped_column("Name", String(50))
product_number: Mapped[str] = mapped_column("ProductNumber", String(25))
color: Mapped[str | None] = mapped_column("Color", String(15))
list_price: Mapped[Decimal] = mapped_column("ListPrice", Numeric(19, 4))
standard_cost: Mapped[Decimal] = mapped_column("StandardCost", Numeric(19, 4))
size: Mapped[str | None] = mapped_column("Size", String(5))
product_category_id: Mapped[int | None] = mapped_column("ProductCategoryID", Integer)
sell_start_date: Mapped[datetime] = mapped_column("SellStartDate", DateTime)
modified_date: Mapped[datetime] = mapped_column(
"ModifiedDate", DateTime, server_default=func.getdate()
)
Tip
Microsoft SQL, otomatik olarak sütun artırma için kullanırIDENTITY.
SQLAlchemy bunu tam sayı birincil anahtar sütunları için otomatik olarak eşler. Yukarıda gösterilen açık Identity() ifade isteğe bağlıdır, başlangıç ve artış değerlerini kontrol etmeniz gerekmedikçe.
CRUD operasyonları
Aşağıdaki örnekler, ORM oturumu kullanılarak satır ekleme, sorgulama, güncelleme ve silme yöntemlerini gösterir. Her örnek, bir satır eklediğinizde döndürülen ProductID olan new_id öğesini yeniden kullanır. Dört işlemi birlikte çalıştırmak için tam örneği görün.
Oturum oluşturma
Bir işlem içinde işlemleri yürütmek için bir oturum oluşturun:
from sqlalchemy.orm import Session
with Session(engine) as session:
# Use session for queries and modifications
pass
Birçok oturum oluşturan uygulamalar için şunları kullanın sessionmaker:
from sqlalchemy.orm import sessionmaker
SessionLocal = sessionmaker(bind=engine)
Satır ekleme
Yeni bir ürün ekleyin, oturumu kaydedin ve aşağıdaki örnekler için oluşturulan ProductID öğesini yakalayın:
from datetime import datetime
with Session(engine) as session:
product = Product(
name="Classic Road Bike",
product_number="BK-C001",
color="Red",
list_price=Decimal("1299.99"),
standard_cost=Decimal("749.99"),
sell_start_date=datetime(2026, 1, 1),
product_category_id=6,
)
session.add(product)
session.commit()
new_id = product.product_id
print(f"Inserted ProductID: {new_id}")
Note
SalesLT.Product içinde, hem Name hem de ProductNumber benzersiz kısıtlamalara sahiptir. Bu eklemeyi birden fazla kez çalıştırırsanız, bu değerleri değiştirin veya önce önceki satırı silin.
Tam örnek, oluşturduğu satırı siler, böylece tekrar tekrar çalıştırabilir.
Sorgu satırları
Birincil anahtarla tek bir satırı alın veya filtrelenmiş sorgular için kullanın select() :
from sqlalchemy import select
with Session(engine) as session:
# Single row by primary key (new_id is from the insert example)
product = session.get(Product, new_id)
if product:
print(f"{product.name}: ${product.list_price}")
# Filtered query
stmt = select(Product).where(Product.list_price < 500).order_by(Product.name)
products = session.scalars(stmt).all()
for p in products:
print(f"{p.name}: ${p.list_price}")
Satırları güncelleştirme
Mevcut bir satırdaki bir alanı değiştirin ve commit yapın:
with Session(engine) as session:
product = session.get(Product, new_id)
if product:
product.list_price = Decimal("1349.99")
session.commit()
Satırları silme
Bir satırı kaldır ve commit et:
with Session(engine) as session:
product = session.get(Product, new_id)
if product:
session.delete(product)
session.commit()
Tam örnek
Önceki bölümler her parçayı ayrı ayrı gösteriyordu. Bu bölüm, bunları kopyalayıp çalıştırıp tekrar çalıştırabileceğiniz tek bir bağımsız betikte birleştiriyor.
crud.py adlı bir dosya oluşturun ve aşağıdaki kodu ekleyin. Bağlantı detaylarını create_engine kendi bilgilerinizle değiştirin ( bkz. Bağlantı URL'leri):
from datetime import datetime
from decimal import Decimal
from sqlalchemy import create_engine, Identity, String, Numeric, Integer, DateTime, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column, Session
# Replace <password> and <database> with your connection details.
engine = create_engine(
"mssql+mssqlpython://dbuser:<password>@localhost:1433/<database>"
)
class Base(DeclarativeBase):
pass
class Product(Base):
__tablename__ = "Product"
__table_args__ = {"schema": "SalesLT"}
product_id: Mapped[int] = mapped_column(
"ProductID", Integer, Identity(), primary_key=True
)
name: Mapped[str] = mapped_column("Name", String(50))
product_number: Mapped[str] = mapped_column("ProductNumber", String(25))
color: Mapped[str | None] = mapped_column("Color", String(15))
list_price: Mapped[Decimal] = mapped_column("ListPrice", Numeric(19, 4))
standard_cost: Mapped[Decimal] = mapped_column("StandardCost", Numeric(19, 4))
size: Mapped[str | None] = mapped_column("Size", String(5))
product_category_id: Mapped[int | None] = mapped_column("ProductCategoryID", Integer)
sell_start_date: Mapped[datetime] = mapped_column("SellStartDate", DateTime)
modified_date: Mapped[datetime] = mapped_column(
"ModifiedDate", DateTime, server_default=func.getdate()
)
with Session(engine) as session:
# Create
product = Product(
name="Classic Road Bike",
product_number="BK-C001",
color="Red",
list_price=Decimal("1299.99"),
standard_cost=Decimal("749.99"),
sell_start_date=datetime(2026, 1, 1),
product_category_id=6,
)
session.add(product)
session.commit()
new_id = product.product_id
print(f"Inserted ProductID: {new_id}")
# Read
product = session.get(Product, new_id)
print(f"Read: {product.name} costs ${product.list_price}")
# Update
product.list_price = Decimal("1349.99")
session.commit()
print(f"Updated price to ${product.list_price}")
# Delete
session.delete(product)
session.commit()
print(f"Deleted ProductID: {new_id}")
Betiği Çalıştırın:
python crud.py
Aşağıdaki gibi bir çıktı görüyorsunuz:
Inserted ProductID: 1019
Read: Classic Road Bike costs $1299.9900
Updated price to $1349.9900
Deleted ProductID: 1019
Komut dosyası, oluşturduğu satırı siler; böylece yeniden çalıştırdığınızda Name ve ProductNumber üzerindeki benzersiz kısıtlamaları ihlal etmez. Her çalıştırma yeni bir satır ekler, bu yüzden ProductID her seferinde artar.
Temel sorgular
SQLAlchemy Core, daha düşük seviyeli bir SQL ifade API'si sağlar. Core'u aynı motor ve tablo tanımlarında, ORM haritalı sınıflar da dahil olmak üzere kullanabilirsiniz.
from sqlalchemy import text
with engine.connect() as conn:
result = conn.execute(text("SELECT @@VERSION"))
print(result.scalar())
Tip güvenli SQL üretimi için tablo düzeyinde yapılar kullanın:
from sqlalchemy import insert, select, update, delete
with engine.connect() as conn:
# Insert
conn.execute(
insert(Product).values(
name="Touring Bike",
product_number="BK-T002",
list_price=Decimal("999.99"),
standard_cost=Decimal("575.00"),
sell_start_date=datetime(2026, 1, 1)
)
)
conn.commit()
# Select
stmt = select(
Product.name.label("name"),
Product.list_price.label("list_price"),
).where(Product.list_price > 100)
for row in conn.execute(stmt):
print(row.name, row.list_price)
# Delete the inserted row so this example can run again
conn.execute(delete(Product).where(Product.product_number == "BK-T002"))
conn.commit()
Note
Veritabanındaki adı öznitelik adından farklı olan tek tek eşlenmiş sütunları seçtiğinizde (örneğin, Product.name, Name sütununa eşlenir), Core satırları veritabanı sütun adına göre anahtarlanır. Değere row.Name yerine row.name olarak erişmek için .label("name") ekleyin.
Bağlantı havuzlama
SQLAlchemy varsayılan olarak bir bağlantı havuzunu yönetir. İş yükünüz için havuz ayarlarını ayarlayın:
engine = create_engine(
"mssql+mssqlpython://dbuser:<password>@localhost/<database>",
pool_size=10,
max_overflow=20,
pool_timeout=30,
pool_recycle=3600,
)
| Parametre | Açıklama |
|---|---|
pool_size |
Açık tutulacak bağlantı sayısı (varsayılan: 5). |
max_overflow |
pool_size üzerinde izin verilen bağlantılar (varsayılan: 10). |
pool_timeout |
Hata oluşturmadan önce bağlantı için beklenecek saniye sayısı (varsayılan: 30). |
pool_recycle |
Saniyeler sonra bağlantı geri dönüştürülür (varsayılan: -1, devre dışı bırakılır). Veritabanınız boşta bağlantıları kapatıyorsa bu değeri ayarlayın. |
Web çerçeveleriyle kullanım
SQLAlchemy , genellikle Flask ve FastAPI için veritabanı katmanı olarak kullanılır. mssql-python lehçesi, SQLAlchemy'yi destekleyen herhangi bir çerçeveyle çalışır.
Aşağıdaki kod parçacıkları, her çerçeve için önerilen istek başına bir oturum düzenini gösterir. Bunlar, önceki bölümlerdeki engine ve Product modelini varsayan açıklayıcı parçalardır; tam uygulamalar değildir. Tam ve çalıştırılabilir uygulamalar için FastAPI entegrasyonu ve Flask entegrasyon makalelerine bakınız.
FastAPI örneği
İstek başına bir oturum sağlamak için bir jeneratör bağımlılığı kullanın:
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy import create_engine
engine = create_engine("mssql+mssqlpython://dbuser:<password>@<server>/<database>")
SessionLocal = sessionmaker(bind=engine)
app = FastAPI()
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.get("/products/{product_id}")
def read_product(product_id: int, db: Session = Depends(get_db)):
product = db.get(Product, product_id)
if not product:
raise HTTPException(status_code=404, detail="Product not found")
return {"name": product.name, "price": float(product.list_price)}
Matla örneği
Oturumu isteğe bağlamak için bir bağlam yöneticisi kullanın:
from flask import Flask, jsonify
from sqlalchemy.orm import Session, sessionmaker
from sqlalchemy import create_engine
engine = create_engine("mssql+mssqlpython://dbuser:<password>@<server>/<database>")
SessionLocal = sessionmaker(bind=engine)
app = Flask(__name__)
@app.route("/products/<int:product_id>")
def read_product(product_id):
with SessionLocal() as session:
product = session.get(Product, product_id)
if not product:
return jsonify({"error": "Not found"}), 404
return jsonify({"name": product.name, "price": float(product.list_price)})
Alembik göçler
Alembic , SQLAlchemy projeleri için şema geçişlerini yönetir ve mssql-python lehçesiyle çalışır. Alembic'in otomatik oluşturma özelliği, modellerinizi canlı veritabanıyla karşılaştırıyor, bu yüzden birkaç ekstra adım, yönetemediğiniz tablolara değişiklik önermesini engelliyor.
Alembic'i kur
Alembic'i kur ve bir göç dizinini başlat:
pip install alembic
alembic init migrations
Bağlantı URL'sini ayarlayın alembic.ini:
sqlalchemy.url = mssql+mssqlpython://dbuser:<password>@localhost/<database>
Alembic'i modellerinize yöneltin
Otomatik oluşturma modellerinizin meta verilerine ihtiyaç duyar. Alembic'in yönettiği modelleri aktarılabilir bir modüle koyun, örneğin models.py. Otomatik üretim, bir modelde yer almayan herhangi bir sütunun kaldırılmasını önerdiği için, bu makalenin önceki bölümünde kullanılan basitleştirilmiş Product modelini yeniden kullanmak yerine tablosunun tamamını kapsayan bir model tanımlayın:
# models.py
from datetime import datetime
from sqlalchemy import Identity, String, Integer, DateTime, func
from sqlalchemy.orm import DeclarativeBase, Mapped, mapped_column
class Base(DeclarativeBase):
pass
class ProductReview(Base):
__tablename__ = "ProductReview"
__table_args__ = {"schema": "SalesLT"}
review_id: Mapped[int] = mapped_column("ReviewID", Integer, Identity(), primary_key=True)
product_id: Mapped[int] = mapped_column("ProductID", Integer)
reviewer_name: Mapped[str] = mapped_column("ReviewerName", String(50))
rating: Mapped[int] = mapped_column("Rating", Integer)
comments: Mapped[str | None] = mapped_column("Comments", String(500))
modified_date: Mapped[datetime] = mapped_column("ModifiedDate", DateTime, server_default=func.getdate())
Caution
Varsayılan olarak, otomatik oluşturma veritabanındaki target_metadata içinde olmayan her tabloyu kaldırılmış kabul eder ve bunun için drop_table üretir. AdventureWorksLT gibi mevcut bir veritabanına karşı, bu işlem onlarca tabloyu düşürebilir. Alembic'in sadece modellerinizin tanımladığı tabloları yönetmesi için bir include_name filtre ekleyin ve uygulamadan önce oluşturulan betikleri her zaman gözden geçirin.
migrations/env.py içinde, target_metadata = None öğesini aşağıdaki kodla değiştirin. Modellerinizi içe aktarır ve otomatik oluşturmayı, tanımladıkları şema ve tablolarla sınırlar:
from models import Base
target_metadata = Base.metadata
# Limit autogenerate to the tables your models define.
managed_schemas = {table.schema for table in target_metadata.tables.values()}
managed_tables = {table.name for table in target_metadata.tables.values()}
def include_name(name, type_, parent_names):
if type_ == "schema":
return name in managed_schemas
if type_ == "table":
return name in managed_tables
return True
Hem run_migrations_offline hem de run_migrations_online içinde include_name ve include_schemas=True değerlerini context.configure'ye iletin. Bu include_schemas=True ayar, Alembic'in varsayılan olmayan şemalarda tabloları görmesini sağlıyor, örneğin SalesLT:
context.configure(
connection=connection,
target_metadata=target_metadata,
include_name=include_name,
include_schemas=True,
)
Bir göç oluşturun ve uygulayın
Modellerinizden bir migrasyon oluşturun:
alembic revision --autogenerate -m "add product review table"
Alembic yeni tabloyu algılar ve bir göç betiği yazar:
INFO [alembic.autogenerate.compare.tables] Detected added table 'SalesLT.ProductReview'
Generating .../versions/xxxx_add_product_review_table.py ... done
Oluşturulan upgrade() tabloyu oluşturur, downgrade() ise tabloyu siler:
def upgrade() -> None:
op.create_table(
"ProductReview",
sa.Column("ReviewID", sa.Integer(), sa.Identity(always=False), nullable=False),
sa.Column("ProductID", sa.Integer(), nullable=False),
sa.Column("ReviewerName", sa.String(length=50), nullable=False),
sa.Column("Rating", sa.Integer(), nullable=False),
sa.Column("Comments", sa.String(length=500), nullable=True),
sa.Column("ModifiedDate", sa.DateTime(), server_default=sa.text("getdate()"), nullable=False),
sa.PrimaryKeyConstraint("ReviewID"),
schema="SalesLT",
)
def downgrade() -> None:
op.drop_table("ProductReview", schema="SalesLT")
Script'i inceleyin ve ardından tüm bekleyen göçleri uygulayın:
alembic upgrade head
pyodbc diyalektinden farklar
Eğer mssql+pyodbc sürücüsünden geçiş yapıyorsanız, mssql-python diyalekti benzerdir; çünkü her iki sürücü de aynı ODBC altyapısına dayanır. Önemli farklar:
| Konu | mssql+pyodbc |
mssql+mssqlpython |
|---|---|---|
| ODBC sürücü kurulumu | Ayrı bir ODBC sürücüsü gerektirir (örneğin, Microsoft SQL için ODBC Driver 18). | Sürücü dahildir. Ayrı bir ODBC sürücüsü gerekmiyor. |
| Bağlantı URL'si | mssql+pyodbc://user:pass@host/db?driver=ODBC+Driver+18+for+SQL+Server |
mssql+mssqlpython://user:pass@host/db |
fast_executemany |
create_engine(..., fast_executemany=True) aracılığıyla desteklenir. |
Uygulanamaz. Sürücü, toplu performansı dahili olarak yönetir. |
| Availability | Stabil, 1.x'ten beri SQLAlchemy'ye dahil edilmiştir. | Ön sürüm (SQLAlchemy 2.1.0b2+). |
Bilinen Sınırlamalar
SQLAlchemy için mssql-python lehçesi ön sürüm aşamasındadır. Üretimde kullanmadan önce şu sonuçları anlayın:
API Değişiklikleri: Metod imzaları, istisna türleri ve davranışlar son kararlı sürümden önce değişebilir. Her zaman SQLAlchemy sürümünüzü belirli bir ön sürüm sürümüne sabitleyin (örneğin,
sqlalchemy==2.1.0b2) ve yükseltmeleri iyice test edin.Sınırlı Testler: Lehçe, kararlı
mssql+pyodbclehçeye göre daha az topluluk testi içerir. İstisnai durumlarla veya eksik işlevlerle karşılaşabilirsiniz.Özellik Boşlukları: Bazı gelişmiş ORM veya Core özellikleri çalışmayabilir. SQLAlchemy MSSQL lehçe dokümantasyonuna bakın ve bir projeye başlamadan önce kullanım durumlarınızı test edin.
Destek Garantisi Yok: Microsoft ve SQLAlchemy en iyi şekilde destek sağlar, ancak sorunlar stabil sürümden önce çözülmeyebilir.
Ön Sürümün Ne Zaman Kullanılacağı:
- Geliştirme ve test ortamları
- Kavram kanıtı projeleri
- Harici ODBC sürücüsü bağımlılığından kaçınmak istiyorsanız
mssql+pyodbckaynağından geçiş - API değişikliklerine yanıt verebileceğiniz ve regresyon testi yapabileceğiniz projeler
Ön Sürüm Kullanımını Ne Zaman Kullanmamalı:
- Sıkı stabilite gereksinimlerine sahip üretim sistemleri
- Bağımlılık güncellemelerinin nadir olduğu çok yıllık eski uygulamalar
- SQLAlchemy 2.1 stabil GA'ya ulaşana kadar kritik iş yükleri
En son ön sürüm lehçe durumu ve bilinen sorunlar için mssql-python GitHub deposunu kontrol edin.
Sorun giderme
"'sqlalchemy.dialects.mssql.mssqlpython' adlı modül yok"
Bu hata, yüklenmiş SQLAlchemy sürümünüzün mssql-python lehçesini içermediği anlamına gelir. 2.1.0b2 veya daha yeni bir sürümüne sahip olduğunuzu doğrulayın:
pip install "sqlalchemy>=2.1.0b2"
Bağlantı hataları
Eğer create_engine başarılı olursa ama sorgular başarısız olursa, bağlantı parametrelerinizin doğrudan mssql-python ile çalıştığını doğrulayın:
import mssql_python
conn = mssql_python.connect(
"Server=localhost;Database=<database>;UID=dbuser;PWD=<password>;Encrypt=yes"
)
cursor = conn.cursor()
cursor.execute("SELECT 1")
print(cursor.fetchone())
conn.close()
Doğrudan bağlantı çalışıyorsa ama SQLAlchemy çalışmıyorsa, şifreniz veya sunucu adınızdaki özel karakterlerle URL kodlama sorunlarını kontrol edin.