SQLAlchemy - Hızlı Kılavuz

SQLAlchemy, popüler bir SQL araç setidir ve Object Relational Mapper. YazılmıştırPythonve bir uygulama geliştiricisine SQL'in tam gücünü ve esnekliğini verir. O biropen source ve cross-platform software MIT lisansı altında yayınlandı.

SQLAlchemy, sınıflar veritabanına eşlenebilen nesne-ilişkisel eşleştiricisi (ORM) ile ünlüdür, böylece nesne modeli ve veritabanı şemasının baştan temiz bir şekilde ayrıştırılmış bir şekilde geliştirilmesine izin verir.

SQL veritabanlarının boyutu ve performansı önem kazandıkça, nesne koleksiyonları gibi davranmazlar. Öte yandan nesne koleksiyonlarında soyutlama önem kazandıkça daha az tablo ve satır gibi davranırlar. SQLAlchemy, bu ilkelerin her ikisine de uyum sağlamayı amaçlamaktadır.

Bu nedenle data mapper pattern (like Hibernate) rather than the active record pattern used by a number of other ORMs. Veritabanları ve SQL, SQLAlchemy kullanılarak farklı bir bakış açısıyla görüntülenecektir.

Michael Bayer, SQLAlchemy'nin orijinal yazarıdır. İlk sürümü Şubat 2006'da yayınlandı. En son sürüm 1.2.7 olarak numaralandırıldı ve en son Nisan 2018'de yayınlandı.

ORM nedir?

ORM (Object Relational Mapping), nesne yönelimli programlama dillerinde uyumsuz tip sistemler arasında veri dönüştürmek için bir programlama tekniğidir. Genellikle, Python gibi Nesne Yönelimli (OO) bir dilde kullanılan tür sistemi, skaler olmayan türleri içerir. Bunlar, tam sayılar ve dizeler gibi ilkel türler olarak ifade edilemez. Bu nedenle, OO programcısının arka uç veritabanıyla etkileşim kurmak için skaler verilerdeki nesneleri dönüştürmesi gerekir. Ancak, Oracle, MySQL vb. Gibi veritabanı ürünlerinin çoğundaki veri türleri birincildir.

Bir ORM sisteminde, her sınıf temel alınan veritabanındaki bir tabloyla eşleşir. Sıkıcı veritabanı arabirim kodunu kendiniz yazmak yerine, siz sistemin mantığını programlamaya odaklanabilirken, bir ORM sizin için bu sorunları halleder.

SQLAlchemy - Ortam kurulumu

SQLAlchemy'yi kullanmak için gerekli çevre kurulumunu tartışalım.

2.7'den yüksek herhangi bir Python sürümü SQLAlchemy'yi kurmak için gereklidir. Yüklemenin en kolay yolu Python Paket Yöneticisi'ni kullanmaktır,pip. Bu yardımcı program, standart Python dağıtımıyla birlikte gelir.

pip install sqlalchemy

Yukarıdaki komutu kullanarak, latest released versionSQLAlchemy'yi python.org'dan yükleyin ve sisteminize yükleyin.

Python'un anaconda dağıtımı durumunda, SQLAlchemy şuradan yüklenebilir: conda terminal aşağıdaki komutu kullanarak -

conda install -c anaconda sqlalchemy

SQLAlchemy'yi aşağıdaki kaynak kodundan kurmak da mümkündür -

python setup.py install

SQLAlchemy, belirli bir veritabanı için oluşturulmuş bir DBAPI uygulaması ile çalışmak üzere tasarlanmıştır. Çeşitli DBAPI uygulamaları ve veritabanları ile iletişim kurmak için lehçe sistemini kullanır. Tüm lehçeler, uygun bir DBAPI sürücüsünün kurulu olmasını gerektirir.

Aşağıdakiler dahil olan lehçelerdir -

  • Firebird
  • Microsoft SQL Sunucusu
  • MySQL
  • Oracle
  • PostgreSQL
  • SQLite
  • Sybase

SQLAlchemy'nin düzgün bir şekilde kurulup kurulmadığını kontrol etmek ve sürümünü öğrenmek için Python istemine aşağıdaki komutu girin -

>>> import sqlalchemy
>>>sqlalchemy.__version__
'1.2.7'

SQLAlchemy çekirdeği şunları içerir: SQL rendering engine, DBAPI integration, transaction integration, ve schema description services. SQLAlchemy çekirdeği, birschema-centric usage paradigma, SQLAlchemy ORM ise domain-centric mode of usage.

SQL İfade Dili, Python yapılarını kullanarak ilişkisel veritabanı yapılarını ve ifadelerini temsil eden bir sistem sunar. İlişkisel veritabanının ilkel yapılarını doğrudan görüş olmadan temsil eden bir sistem sunar; bu, İfade Dilinin uygulamalı kullanımının bir örneği olan yüksek düzeyde ve soyutlanmış bir kullanım modeli sunan ORM'nin aksine.

İfade Dili, SQLAlchemy'nin temel bileşenlerinden biridir. Programcının Python kodunda SQL ifadeleri belirtmesine ve bunu doğrudan daha karmaşık sorgularda kullanmasına olanak tanır. İfade dili arka uçtan bağımsızdır ve ham SQL'in her yönünü kapsamlı bir şekilde kapsar. Ham SQL'e, SQLAlchemy'deki diğer bileşenlerden daha yakındır.

İfade Dili, doğrudan ilişkisel veritabanının ilkel yapılarını temsil eder. ORM, İfade dilinin üstüne dayandığından, tipik bir Python veritabanı uygulaması, her ikisinin de örtüşen kullanımına sahip olabilir. Uygulama, uygulama konseptlerini ayrı veritabanı sorgularına çevirmek için kendi sistemini tanımlaması gerekse de, ifade dilini tek başına kullanabilir.

İfade dili ifadeleri, SQLAlchemy motoru tarafından karşılık gelen ham SQL sorgularına çevrilecektir. Şimdi motoru nasıl oluşturacağımızı ve yardımıyla çeşitli SQL sorgularını nasıl yürüteceğimizi öğreneceğiz.

Önceki bölümde, SQLAlchemy'de ifade Dili hakkında tartışmıştık. Şimdi bir veritabanına bağlanmanın adımlarına geçelim.

Motor sınıfı bir Pool and Dialect together bir veritabanı kaynağı sağlamak connectivity and behavior. Engine sınıfının bir nesnesi,create_engine() işlevi.

Create_engine () işlevi, veritabanını bir bağımsız değişken olarak alır. Veritabanının herhangi bir yerde tanımlanması gerekli değildir. Standart çağrı formu, URL'yi ilk konumsal argüman olarak göndermelidir, genellikle veritabanı diyalektini ve bağlantı argümanlarını gösteren bir dize. Aşağıda verilen kodu kullanarak bir veritabanı oluşturabiliriz.

>>> from sqlalchemy import create_engine
>>> engine = create_engine('sqlite:///college.db', echo = True)

Bir MySQL database, aşağıdaki komutu kullanın -

engine = create_engine("mysql://user:pwd@localhost/college",echo = True)

Özellikle belirtmek için DB-API bağlantı için kullanılacak URL string aşağıdaki formu alır -

dialect[+driver]://user:password@host/dbname

Örneğin, kullanıyorsanız PyMySQL driver with MySQL, aşağıdaki komutu kullanın -

mysql+pymysql://<username>:<password>@<host>/<dbname>

echo flagPython'un standart günlükleme modülü aracılığıyla gerçekleştirilen SQLAlchemy günlüğünü kurmak için bir kısayoldur. Sonraki bölümlerde, üretilen tüm SQL'leri öğreneceğiz. Ayrıntılı çıktıyı gizlemek için echo niteliğini şu şekilde ayarlayın:None. Create_engine () işlevinin diğer argümanları, diyalekte özgü olabilir.

Create_engine () işlevi bir Engine object. Engine sınıfının bazı önemli yöntemleri şunlardır -

Sr.No. Yöntem ve Açıklama
1

connect()

Bağlantı nesnesini döndürür

2

execute()

Bir SQL deyimi yapısını yürütür

3

begin()

Oluşturulan bir İşlemle Bağlantı sağlayan bir bağlam yöneticisi döndürür. İşlem başarıyla tamamlandıktan sonra İşlem tamamlanır, aksi takdirde geri alınır

4

dispose()

Motor tarafından kullanılan bağlantı havuzunu ortadan kaldırır

5

driver()

Motor tarafından kullanılan Lehçenin sürücü adı

6

table_names()

Veritabanında bulunan tüm tablo adlarının bir listesini verir

7

transaction()

Verilen işlevi bir işlem sınırı içinde yürütür

Şimdi tablo oluşturma işlevinin nasıl kullanılacağını tartışalım.

SQL İfade Dili, ifadelerini tablo sütunlarına göre oluşturur. SQLAlchemy Column nesnesi bircolumn sırayla bir ile temsil edilen bir veritabanı tablosunda Tableobject. Meta veriler, tabloların tanımlarını ve dizin, görünüm, tetikleyiciler gibi ilişkili nesneler içerir.

Dolayısıyla, SQLAlchemy Metadata'daki MetaData sınıfının bir nesnesi, Tablo nesnelerinin ve bunlarla ilişkili şema yapılarının bir koleksiyonudur. Bir Motor veya Bağlantı için isteğe bağlı bir bağlamanın yanı sıra bir Tablo nesneleri koleksiyonunu tutar.

from sqlalchemy import MetaData
meta = MetaData()

MetaData sınıfının oluşturucusu, varsayılan olarak olan bağlama ve şema parametrelerine sahip olabilir None.

Ardından, tablolarımızı yukarıdaki meta veri kataloğunda kullanarak tanımlarız. the Table construct, normal SQL CREATE TABLE deyimine benzeyen.

Table sınıfının bir nesnesi, bir veritabanındaki karşılık gelen tabloyu temsil eder. Yapıcı aşağıdaki parametreleri alır -

İsim Tablonun adı
Meta veriler Bu tabloyu tutacak MetaData nesnesi
Sütun (lar) Bir veya daha fazla sütun sınıfı nesnesi

Sütun nesnesi bir column içinde database table. Oluşturucu, adı, türü ve birincil_anahtar, otomatik artırma ve diğer kısıtlamalar gibi diğer parametreleri alır.

SQLAlchemy, Python verilerini içinde tanımlanan olası en iyi genel sütun veri türleriyle eşleştirir. Genel veri türlerinden bazıları -

  • BigInteger
  • Boolean
  • Date
  • DateTime
  • Float
  • Integer
  • Numeric
  • SmallInteger
  • String
  • Text
  • Time

Oluşturmak için students table üniversite veritabanında aşağıdaki parçacığı kullanın -

from sqlalchemy import Table, Column, Integer, String, MetaData
meta = MetaData()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

Create_all () işlevi, tanımlanmış tüm tablo nesnelerini oluşturmak için motor nesnesini kullanır ve bilgileri meta verilerde depolar.

meta.create_all(engine)

Aşağıda, içinde bir öğrenci tablosu bulunan bir SQLite veritabanı college.db oluşturacak tam kod verilmiştir.

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String),
)
meta.create_all(engine)

Create_engine () işlevinin echo özniteliği şu şekilde ayarlanmıştır: Truekonsol, tablo oluşturma için gerçek SQL sorgusunu aşağıdaki gibi gösterecektir -

CREATE TABLE students (
   id INTEGER NOT NULL,
   name VARCHAR,
   lastname VARCHAR,
   PRIMARY KEY (id)
)

College.db, mevcut çalışma dizininde oluşturulacaktır. Öğrenci tablosunun oluşturulup oluşturulmadığını kontrol etmek için, veritabanını herhangi bir SQLite GUI aracını kullanarak açabilirsiniz.SQLiteStudio.

Aşağıdaki görüntü, veritabanında oluşturulan öğrenci tablosunu göstermektedir -

Bu bölümde kısaca SQL İfadelerine ve işlevlerine odaklanacağız.

SQL ifadeleri, hedef tablo nesnesine göre ilgili yöntemler kullanılarak oluşturulur. Örneğin, INSERT ifadesi aşağıdaki gibi insert () yöntemi çalıştırılarak oluşturulur -

ins = students.insert()

Yukarıdaki yöntemin sonucu, kullanılarak doğrulanabilen bir ekleme nesnesidir str()işlevi. Aşağıdaki kod, öğrenci kimliği, adı, soyadı gibi ayrıntıları ekler.

'INSERT INTO students (id, name, lastname) VALUES (:id, :name, :lastname)'

Belirli bir alana değer girmek mümkündür. values()nesne ekleme yöntemi. Aynı kod aşağıda verilmiştir -

>>> ins = users.insert().values(name = 'Karan')
>>> str(ins)
'INSERT INTO users (name) VALUES (:name)'

Python konsolunda yankılanan SQL, gerçek değeri göstermez (bu durumda 'Karan'). Bunun yerine, SQLALchemy, ifadenin derlenmiş biçiminde görülebilen bir bağlama parametresi oluşturur.

ins.compile().params
{'name': 'Karan'}

Benzer şekilde, gibi yöntemler update(), delete() ve select()sırasıyla UPDATE, DELETE ve SELECT ifadeleri oluşturun. Onları sonraki bölümlerde öğreneceğiz.

Önceki bölümde SQL İfadelerini öğrendik. Bu bölümde, bu ifadelerin uygulanmasına bakacağız.

Ortaya çıkan SQL ifadelerini yürütmek için, obtain a connection object representing an actively checked out DBAPI connection resource ve sonra feed the expression object aşağıdaki kodda gösterildiği gibi.

conn = engine.connect()

Aşağıdaki insert () nesnesi execute () yöntemi için kullanılabilir -

ins = students.insert().values(name = 'Ravi', lastname = 'Kapoor')
result = conn.execute(ins)

Konsol, SQL ifadesinin yürütülmesinin sonucunu aşağıdaki gibi gösterir -

INSERT INTO students (name, lastname) VALUES (?, ?)
('Ravi', 'Kapoor')
COMMIT

Aşağıda, INSERT sorgusunun SQLAlchemy'nin temel tekniğini kullanarak yürütülmesini gösteren parçacığın tamamı verilmiştir -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

ins = students.insert()
ins = students.insert().values(name = 'Ravi', lastname = 'Kapoor')
conn = engine.connect()
result = conn.execute(ins)

Sonuç, aşağıdaki ekran görüntüsünde gösterildiği gibi SQLite Studio kullanılarak veritabanı açılarak doğrulanabilir -

Sonuç değişkeni ResultProxy olarak bilinir object. DBAPI imleç nesnesine benzer. İfademizden oluşturulan birincil anahtar değerler hakkında bilgi edinebiliriz.ResultProxy.inserted_primary_key aşağıda gösterildiği gibi -

result.inserted_primary_key
[1]

DBAPI'nin execute many () yöntemini kullanarak birçok ekleme yapmak için, her biri eklenecek farklı bir parametre seti içeren bir sözlük listesi gönderebiliriz.

conn.execute(students.insert(), [
   {'name':'Rajiv', 'lastname' : 'Khanna'},
   {'name':'Komal','lastname' : 'Bhandari'},
   {'name':'Abdul','lastname' : 'Sattar'},
   {'name':'Priya','lastname' : 'Rajhans'},
])

Bu, aşağıdaki şekilde gösterildiği gibi tablonun veri görünümüne yansıtılır -

Bu bölümde, tablo nesnesindeki satırları seçme kavramını tartışacağız.

Tablo nesnesinin select () yöntemi, construct SELECT expression.

s = students.select()

Seçilen nesnenin çevirisi SELECT query by str(s) function aşağıda gösterildiği gibi -

'SELECT students.id, students.name, students.lastname FROM students'

Aşağıdaki kodda gösterildiği gibi bağlantı nesnesinin () yöntemini çalıştırmak için bu seçme nesnesini bir parametre olarak kullanabiliriz -

result = conn.execute(s)

Yukarıdaki ifade çalıştırıldığında, Python kabuğu eşdeğer SQL ifadesinin ardından yankılanır -

SELECT students.id, students.name, students.lastname
FROM students

Ortaya çıkan değişken, DBAPI'deki imlecin bir eşdeğeridir. Şimdi kullanarak kayıtları getirebilirizfetchone() method.

row = result.fetchone()

Tablodaki tüm seçili satırlar bir for loop aşağıda verildiği gibi -

for row in result:
   print (row)

Öğrenci tablosundaki tüm satırları yazdırmak için eksiksiz kod aşağıda gösterilmiştir -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

s = students.select()
conn = engine.connect()
result = conn.execute(s)

for row in result:
   print (row)

Python kabuğunda gösterilen çıktı aşağıdaki gibidir -

(1, 'Ravi', 'Kapoor')
(2, 'Rajiv', 'Khanna')
(3, 'Komal', 'Bhandari')
(4, 'Abdul', 'Sattar')
(5, 'Priya', 'Rajhans')

SELECT sorgusunun WHERE yan tümcesi kullanılarak uygulanabilir Select.where(). Örneğin, id> 2 olan satırları görüntülemek istiyorsak

s = students.select().where(students.c.id>2)
result = conn.execute(s)

for row in result:
   print (row)

Buraya c attribute is an alias for column. Aşağıdaki çıktı kabukta görüntülenecektir -

(3, 'Komal', 'Bhandari')
(4, 'Abdul', 'Sattar')
(5, 'Priya', 'Rajhans')

Burada, sqlalchemy.sql modülündeki select () fonksiyonu ile seçilen nesnenin de elde edilebileceğini not etmeliyiz. Select () işlevi, tablo nesnesini bağımsız değişken olarak gerektirir.

from sqlalchemy.sql import select
s = select([users])
result = conn.execute(s)

SQLAlchemy, SQL'in zaten bilindiği ve ifadenin dinamik özellikleri desteklemesi için güçlü bir ihtiyaç olmadığı durumlar için dizeleri kullanmanıza izin verir. Text () yapısı, veritabanına çoğunlukla değiştirilmeden iletilen bir metinsel ifade oluşturmak için kullanılır.

Yeni bir TextClause, aşağıdaki kodda gösterildiği gibi doğrudan bir metinsel SQL dizesini temsil eder -

from sqlalchemy import text
t = text("SELECT * FROM students")
result = connection.execute(t)

Avantajlar text() düz bir dize üzerinden sağlar -

  • bağlama parametreleri için arka uçtan bağımsız destek
  • ifade başına yürütme seçenekleri
  • sonuç sütun yazma davranışı

Text () işlevi, adlandırılmış iki nokta biçiminde Bound parametreleri gerektirir. Veritabanı arka ucundan bağımsız olarak tutarlıdırlar. Parametreler için değerler göndermek için, bunları ek argümanlar olarak execute () yöntemine aktarıyoruz.

Aşağıdaki örnek, metinsel SQL'de bağlı parametreler kullanır -

from sqlalchemy.sql import text
s = text("select students.name, students.lastname from students where students.name between :x and :y")
conn.execute(s, x = 'A', y = 'L').fetchall()

Text () işlevi SQL ifadesini aşağıdaki gibi oluşturur -

select students.name, students.lastname from students where students.name between ? and ?

X = 'A' ve y = 'L' değerleri parametre olarak geçirilir. Sonuç, 'A' ve 'L' arasında adlara sahip satırların listesidir -

[('Komal', 'Bhandari'), ('Abdul', 'Sattar')]

Text () yapısı, TextClause.bindparams () yöntemini kullanarak önceden belirlenmiş bağlı değerleri destekler. Parametreler ayrıca aşağıdaki gibi açıkça yazılabilir -

stmt = text("SELECT * FROM students WHERE students.name BETWEEN :x AND :y")

stmt = stmt.bindparams(
   bindparam("x", type_= String), 
   bindparam("y", type_= String)
)

result = conn.execute(stmt, {"x": "A", "y": "L"})

The text() function also be produces fragments of SQL within a select() object that 
accepts text() objects as an arguments. The “geometry” of the statement is provided by 
select() construct , and the textual content by text() construct. We can build a statement 
without the need to refer to any pre-established Table metadata. 

from sqlalchemy.sql import select
s = select([text("students.name, students.lastname from students")]).where(text("students.name between :x and :y"))
conn.execute(s, x = 'A', y = 'L').fetchall()

Ayrıca kullanabilirsin and_() text () işlevi yardımıyla oluşturulan WHERE yan tümcesinde birden çok koşulu birleştirmek için işlev.

from sqlalchemy import and_
from sqlalchemy.sql import select
s = select([text("* from students")]) \
.where(
   and_(
      text("students.name between :x and :y"),
      text("students.id>2")
   )
)
conn.execute(s, x = 'A', y = 'L').fetchall()

Yukarıdaki kod, "A" ve "L" arasında, kimliği 2'den büyük olan satırları getirir. Kodun çıktısı aşağıda verilmiştir -

[(3, 'Komal', 'Bhandari'), (4, 'Abdul', 'Sattar')]

SQL'deki diğer ad, "SELECT * FROM table1 AS a" dediğinizde ortaya çıkan bir tablonun veya SELECT ifadesinin "yeniden adlandırılmış" bir sürümüne karşılık gelir. AS, tablo için yeni bir ad oluşturur. Takma adlar, herhangi bir tablo veya alt sorguya benzersiz bir adla başvurulmasına izin verir.

Tablo olması durumunda, bu aynı tablonun FROM yan tümcesinde birden çok kez adlandırılmasına izin verir. İfadeyle temsil edilen sütunlar için bir ana ad sağlar ve bu ada göre bunlara başvurulmasına izin verir.

SQLAlchemy'de, herhangi bir Tablo, select () yapısı veya diğer seçilebilir nesneler, From Clause.alias()Takma ad yapısı üreten yöntem. Sqlalchemy.sql modülündeki alias () işlevi, genellikle AS anahtar sözcüğünü kullanan bir SQL ifadesi içindeki herhangi bir tabloya veya alt seçime uygulandığı gibi bir takma adı temsil eder.

from sqlalchemy.sql import alias
st = students.alias("a")

Bu takma ad artık öğrenciler tablosuna başvurmak için select () yapısında kullanılabilir -

s = select([st]).where(st.c.id>2)

Bu, aşağıdaki gibi SQL ifadesine çevrilir -

SELECT a.id, a.name, a.lastname FROM students AS a WHERE a.id > 2

Artık bu SQL sorgusunu bağlantı nesnesinin execute () yöntemi ile çalıştırabiliriz. Kodun tamamı aşağıdaki gibidir -

from sqlalchemy.sql import alias, select
st = students.alias("a")
s = select([st]).where(st.c.id > 2)
conn.execute(s).fetchall()

Yukarıdaki kod satırı çalıştırıldığında, aşağıdaki çıktıyı üretir -

[(3, 'Komal', 'Bhandari'), (4, 'Abdul', 'Sattar'), (5, 'Priya', 'Rajhans')]

update() hedef tablo nesnesindeki yöntem eşdeğer UPDATE SQL ifadesini oluşturur.

table.update().where(conditions).values(SET expressions)

values()sonuçta ortaya çıkan güncelleme nesnesindeki yöntem, UPDATE'in SET koşullarını belirtmek için kullanılır. Yok olarak bırakılırsa, SET koşulları, ifadenin yürütülmesi ve / veya derlenmesi sırasında ifadeye iletilen parametrelerden belirlenir.

Where cümlesi, UPDATE ifadesinin WHERE koşulunu açıklayan İsteğe Bağlı bir ifadedir.

Aşağıdaki kod parçacığı, öğrenciler tablosunda 'Khanna'dan' soyad 'sütununun değerini' Kapoor'a değiştirir -

stmt = students.update().where(students.c.lastname == 'Khanna').values(lastname = 'Kapoor')

Stmt nesnesi, çeviren bir güncelleme nesnesidir -

'UPDATE students SET lastname = :lastname WHERE students.lastname = :lastname_1'

Bağlı parametre lastname_1 ne zaman değiştirilecek execute()yöntem çağrılır. Tam güncelleme kodu aşağıda verilmiştir -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()

students = Table(
   'students', 
   meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

conn = engine.connect()
stmt=students.update().where(students.c.lastname=='Khanna').values(lastname='Kapoor')
conn.execute(stmt)
s = students.select()
conn.execute(s).fetchall()

Yukarıdaki kod, verilen ekran görüntüsündeki gibi güncelleme işleminin etkisini gösteren ikinci satırla aşağıdaki çıktıyı görüntüler -

[
   (1, 'Ravi', 'Kapoor'),
   (2, 'Rajiv', 'Kapoor'),
   (3, 'Komal', 'Bhandari'),
   (4, 'Abdul', 'Sattar'),
   (5, 'Priya', 'Rajhans')
]

Benzer işlevselliğin kullanılarak da elde edilebileceğini unutmayın. update() sqlalchemy.sql.expression modülündeki fonksiyon aşağıda gösterildiği gibi -

from sqlalchemy.sql.expression import update
stmt = update(students).where(students.c.lastname == 'Khanna').values(lastname = 'Kapoor')

Önceki bölümde, ne olduğunu anladık. Updateifade eder. Öğreneceğimiz bir sonraki ifadeDelete.

Silme işlemi, aşağıdaki ifadede verildiği gibi hedef tablo nesnesinde delete () yöntemi çalıştırılarak gerçekleştirilebilir -

stmt = students.delete()

Öğrenci tablosu durumunda, yukarıdaki kod satırı aşağıdaki gibi bir SQL ifadesi oluşturur -

'DELETE FROM students'

Ancak bu, öğrenciler tablosundaki tüm satırları silecektir. Genellikle DELETE sorgusu, WHERE yan tümcesi ile belirtilen mantıksal bir ifade ile ilişkilendirilir. Aşağıdaki ifade, parametrenin -

stmt = students.delete().where(students.c.id > 2)

Ortaya çıkan SQL ifadesi, ifade çalıştırıldığında çalışma zamanında değiştirilecek bir bağlı parametreye sahip olacaktır.

'DELETE FROM students WHERE students.id > :id_1'

Aşağıdaki kod örneği, soyadı 'Khanna' olan öğrenci tablosundan bu satırları silecektir -

from sqlalchemy.sql.expression import update
from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)

meta = MetaData()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

conn = engine.connect()
stmt = students.delete().where(students.c.lastname == 'Khanna')
conn.execute(stmt)
s = students.select()
conn.execute(s).fetchall()

Sonucu doğrulamak için SQLiteStudio'da öğrenci tablosunun veri görünümünü yenileyin.

RDBMS'nin önemli özelliklerinden biri de tablolar arasında ilişki kurmaktır. İlgili tablolarda SELECT, UPDATE ve DELETE gibi SQL işlemleri yapılabilir. Bu bölümde SQLAlchemy kullanılarak yapılan bu işlemler açıklanmaktadır.

Bu amaçla SQLite veritabanımızda (college.db) iki tablo oluşturulmuştur. Öğrenci tablosu önceki bölümde verilen yapıya sahiptir; adres tablosunda isest_id eşlenen sütun id column in students table yabancı anahtar kısıtlaması kullanarak.

Aşağıdaki kod, college.db'de iki tablo oluşturacaktır -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ForeignKey
engine = create_engine('sqlite:///college.db', echo=True)
meta = MetaData()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

addresses = Table(
   'addresses', meta, 
   Column('id', Integer, primary_key = True), 
   Column('st_id', Integer, ForeignKey('students.id')), 
   Column('postal_add', String), 
   Column('email_add', String))

meta.create_all(engine)

Yukarıdaki kod, öğrenciler için CREATE TABLE sorgularına ve aşağıdaki gibi adres tablosuna çevrilecek -

CREATE TABLE students (
   id INTEGER NOT NULL,
   name VARCHAR,
   lastname VARCHAR,
   PRIMARY KEY (id)
)

CREATE TABLE addresses (
   id INTEGER NOT NULL,
   st_id INTEGER,
   postal_add VARCHAR,
   email_add VARCHAR,
   PRIMARY KEY (id),
   FOREIGN KEY(st_id) REFERENCES students (id)
)

Aşağıdaki ekran görüntüleri yukarıdaki kodu çok açık bir şekilde göstermektedir -

Bu tablolar yürütülerek verilerle doldurulur insert() methodtablo nesneleri. Öğrenci tablosuna 5 satır eklemek için aşağıda verilen kodu kullanabilirsiniz -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()

conn = engine.connect()
students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

conn.execute(students.insert(), [
   {'name':'Ravi', 'lastname':'Kapoor'},
   {'name':'Rajiv', 'lastname' : 'Khanna'},
   {'name':'Komal','lastname' : 'Bhandari'},
   {'name':'Abdul','lastname' : 'Sattar'},
   {'name':'Priya','lastname' : 'Rajhans'},
])

Rows aşağıdaki kodun yardımıyla adres tablosuna eklenir -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()
conn = engine.connect()

addresses = Table(
   'addresses', meta, 
   Column('id', Integer, primary_key = True), 
   Column('st_id', Integer), 
   Column('postal_add', String), 
   Column('email_add', String)
)

conn.execute(addresses.insert(), [
   {'st_id':1, 'postal_add':'Shivajinagar Pune', 'email_add':'[email protected]'},
   {'st_id':1, 'postal_add':'ChurchGate Mumbai', 'email_add':'[email protected]'},
   {'st_id':3, 'postal_add':'Jubilee Hills Hyderabad', 'email_add':'[email protected]'},
   {'st_id':5, 'postal_add':'MG Road Bangaluru', 'email_add':'[email protected]'},
   {'st_id':2, 'postal_add':'Cannought Place new Delhi', 'email_add':'[email protected]'},
])

Adresler tablosundaki st_id sütununun öğrenciler tablosundaki id sütununa başvurduğuna dikkat edin. Artık bu ilişkiyi her iki tablodan da veri almak için kullanabiliriz. Getirmek istiyoruzname ve lastname adres tablosundaki st_id'ye karşılık gelen öğrenciler tablosundan.

from sqlalchemy.sql import select
s = select([students, addresses]).where(students.c.id == addresses.c.st_id)
result = conn.execute(s)

for row in result:
   print (row)

Seçilen nesneler, ortak ilişki üzerine iki tabloyu birleştiren aşağıdaki SQL ifadesine etkili bir şekilde çevrilir -

SELECT students.id, 
   students.name, 
   students.lastname, 
   addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM students, addresses
WHERE students.id = addresses.st_id

Bu, her iki tablodan aşağıdaki gibi karşılık gelen verileri çıkaran çıktı üretecektir -

(1, 'Ravi', 'Kapoor', 1, 1, 'Shivajinagar Pune', '[email protected]')
(1, 'Ravi', 'Kapoor', 2, 1, 'ChurchGate Mumbai', '[email protected]')
(3, 'Komal', 'Bhandari', 3, 3, 'Jubilee Hills Hyderabad', '[email protected]')
(5, 'Priya', 'Rajhans', 4, 5, 'MG Road Bangaluru', '[email protected]')
(2, 'Rajiv', 'Khanna', 5, 2, 'Cannought Place new Delhi', '[email protected]')

Önceki bölümde, birden çok tablonun nasıl kullanılacağını tartışmıştık. Bu yüzden bir adım daha ileri gidiyoruz ve öğreniyoruzmultiple table updates bu bölümde.

SQLAlchemy'nin tablo nesnesini kullanarak, update () yönteminin WHERE yan tümcesinde birden fazla tablo belirtilebilir. PostgreSQL ve Microsoft SQL Server, birden çok tabloya atıfta bulunan UPDATE deyimlerini destekler. Bu uygular“UPDATE FROM”her seferinde bir tabloyu güncelleyen sözdizimi. Ancak, ek tablolara doğrudan WHERE yan tümcesinde ek bir “FROM” yan tümcesinde başvurulabilir. Aşağıdaki kod satırları,multiple table updates Açıkça.

stmt = students.update().\
values({
   students.c.name:'xyz',
   addresses.c.email_add:'[email protected]'
}).\
where(students.c.id == addresses.c.id)

Güncelleme nesnesi aşağıdaki GÜNCELLEME sorgusuna eşdeğerdir -

UPDATE students 
SET email_add = :addresses_email_add, name = :name 
FROM addresses 
WHERE students.id = addresses.id

MySQL lehçesi söz konusu olduğunda, birden çok tablo aşağıda verildiği gibi virgülle ayrılmış tek bir UPDATE deyimine gömülebilir -

stmt = students.update().\
   values(name = 'xyz').\
   where(students.c.id == addresses.c.id)

Aşağıdaki kod, sonuçta ortaya çıkan UPDATE sorgusunu gösterir -

'UPDATE students SET name = :name 
FROM addresses 
WHERE students.id = addresses.id'

Ancak SQLite lehçesi, UPDATE içinde çoklu tablo kriterlerini desteklemez ve aşağıdaki hatayı gösterir -

NotImplementedError: This backend does not support multiple-table criteria within UPDATE

Ham SQL'in UPDATE sorgusu SET yan tümcesine sahiptir. Kaynak Tablo nesnesinde verilen sütun sıralaması kullanılarak update () yapısı tarafından oluşturulur. Bu nedenle, belirli sütunlara sahip belirli bir UPDATE ifadesi her seferinde aynı şekilde işlenecektir. Parametrelerin kendileri Update.values ​​() yöntemine Python sözlük anahtarları olarak aktarıldığından, başka sabit sıralama yoktur.

Bazı durumlarda, SET yan tümcesinde işlenen parametrelerin sırası önemlidir. MySQL'de, sütun değerlerinde güncelleme sağlamak, diğer sütun değerlerine dayanır.

Aşağıdaki ifadenin sonucu -

UPDATE table1 SET x = y + 10, y = 20

şundan farklı bir sonuca sahip olacak:

UPDATE table1 SET y = 20, x = y + 10

MySQL'deki SET cümlesi, satır başına değil, değer bazında değerlendirilir. Bu amaçla,preserve_parameter_orderkullanıldı. 2-tuples Python listesi, argüman olarak verilir.Update.values() yöntem -

stmt = table1.update(preserve_parameter_order = True).\
   values([(table1.c.y, 20), (table1.c.x, table1.c.y + 10)])

List nesnesi, sıralı olması dışında sözlüğe benzer. Bu, önce "y" sütununun SET yan tümcesinin, ardından "x" sütununun SET yan tümcesinin görüntülenmesini sağlar.

Bu bölümde, Çoklu Tablo Güncellemeleri işlevini kullanmaya benzer Birden Çok Tablo Silme ifadesine bakacağız.

Birçok DBMS lehçesinde DELETE ifadesinin WHERE yan tümcesinde birden fazla tabloya başvurulabilir. PG ve MySQL için, "KULLANIMI SİL" sözdizimi kullanılır; ve SQL Server için "DELETE FROM" ifadesinin kullanılması birden fazla tablo anlamına gelir. SQLAlchemydelete() construct, WHERE yan tümcesinde aşağıdaki gibi birden çok tabloyu belirterek bu modların her ikisini de örtük olarak destekler -

stmt = users.delete().\
   where(users.c.id == addresses.c.id).\
   where(addresses.c.email_address.startswith('xyz%'))
conn.execute(stmt)

Bir PostgreSQL arka ucunda, yukarıdaki ifadeden elde edilen SQL şu şekilde işlenir:

DELETE FROM users USING addresses
WHERE users.id = addresses.id
AND (addresses.email_address LIKE %(email_address_1)s || '%%')

Bu yöntem, bu davranışı desteklemeyen bir veritabanı ile kullanılırsa, derleyici NotImplementedError değerini yükseltir.

Bu bölümde, Joins'in SQLAlchemy'de nasıl kullanılacağını öğreneceğiz.

Birleştirme etkisi, yalnızca iki tablonun columns clause ya da where clauseselect () yapısının. Şimdi join () ve outerjoin () yöntemlerini kullanıyoruz.

Join () yöntemi, bir tablo nesnesinden diğerine bir birleştirme nesnesi döndürür.

join(right, onclause = None, isouter = False, full = False)

Yukarıdaki kodda belirtilen parametrelerin işlevleri aşağıdaki gibidir -

  • right- birleşimin sağ tarafı; bu herhangi bir Tablo nesnesidir

  • onclause- birleştirmenin ON cümlesini temsil eden bir SQL ifadesi. Yok olarak bırakılırsa, iki tabloyu yabancı anahtar ilişkisine göre birleştirmeye çalışır.

  • isouter - True ise, JOIN yerine LEFT OUTER JOIN oluşturur

  • full - True ise, LEFT OUTER JOIN yerine FULL OUTER JOIN oluşturur

Örneğin, join () yönteminin kullanılması, yabancı anahtara göre otomatik olarak birleştirme ile sonuçlanacaktır.

>>> print(students.join(addresses))

Bu, aşağıdaki SQL ifadesine eşdeğerdir -

students JOIN addresses ON students.id = addresses.st_id

Birleştirme kriterlerinden aşağıdaki şekilde açıkça bahsedebilirsiniz -

j = students.join(addresses, students.c.id == addresses.c.st_id)

Şimdi aşağıdaki birleştirmeyi kullanarak aşağıdaki yapıyı oluşturursak -

stmt = select([students]).select_from(j)

Bu, aşağıdaki SQL ifadesine neden olur -

SELECT students.id, students.name, students.lastname
FROM students JOIN addresses ON students.id = addresses.st_id

Bu ifade motoru temsil eden bağlantı kullanılarak yürütülürse, seçilen sütunlara ait veriler görüntülenecektir. Kodun tamamı aşağıdaki gibidir -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ForeignKey
engine = create_engine('sqlite:///college.db', echo = True)

meta = MetaData()
conn = engine.connect()
students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

addresses = Table(
   'addresses', meta, 
   Column('id', Integer, primary_key = True), 
   Column('st_id', Integer,ForeignKey('students.id')), 
   Column('postal_add', String), 
   Column('email_add', String)
)

from sqlalchemy import join
from sqlalchemy.sql import select
j = students.join(addresses, students.c.id == addresses.c.st_id)
stmt = select([students]).select_from(j)
result = conn.execute(stmt)
result.fetchall()

Aşağıdaki, yukarıdaki kodun çıktısıdır -

[
   (1, 'Ravi', 'Kapoor'),
   (1, 'Ravi', 'Kapoor'),
   (3, 'Komal', 'Bhandari'),
   (5, 'Priya', 'Rajhans'),
   (2, 'Rajiv', 'Khanna')
]

Bağlaçlar, SQL ifadelerinin WHERE yan tümcesinde kullanılan ilişkisel işleçleri uygulayan SQLAlchemy modülündeki işlevlerdir. AND, OR, NOT, vb. Operatörleri, iki ayrı mantıksal ifadeyi birleştiren bir bileşik ifade oluşturmak için kullanılır. SELECT deyiminde AND kullanmanın basit bir örneği aşağıdaki gibidir -

SELECT * from EMPLOYEE WHERE salary>10000 AND age>30

SQLAlchemy fonksiyonları ve_ () veya_ () ve not_ () sırasıyla AND, OR ve NOT operatörlerini uygular.

and_ () işlevi

AND ile birleştirilmiş bir ifade birleşimi üretir. Daha iyi anlamak için aşağıda bir örnek verilmiştir -

from sqlalchemy import and_

print(
   and_(
      students.c.name == 'Ravi',
      students.c.id <3
   )
)

Bu, -

students.name = :name_1 AND students.id < :id_1

Bir öğrenci tablosundaki bir select () yapısında and_ () kullanmak için aşağıdaki kod satırını kullanın -

stmt = select([students]).where(and_(students.c.name == 'Ravi', students.c.id <3))

Aşağıdaki nitelikte SELECT ifadesi oluşturulacaktır -

SELECT students.id, 
   students.name, 
   students.lastname
FROM students
WHERE students.name = :name_1 AND students.id < :id_1

Yukarıdaki SELECT sorgusunun çıktısını görüntüleyen tam kod aşağıdaki gibidir -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ForeignKey, select
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()
conn = engine.connect()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

from sqlalchemy import and_, or_
stmt = select([students]).where(and_(students.c.name == 'Ravi', students.c.id <3))
result = conn.execute(stmt)
print (result.fetchall())

Öğrenci tablosunun önceki örnekte kullanılan verilerle doldurulduğu varsayılarak aşağıdaki satır seçilecektir -

[(1, 'Ravi', 'Kapoor')]

or_ () işlevi

OR ile birleştirilen ifadelerin birleşimini üretir. Yukarıdaki örnekte stmt nesnesini or_ () kullanarak aşağıdaki ile değiştireceğiz.

stmt = select([students]).where(or_(students.c.name == 'Ravi', students.c.id <3))

Bu, SELECT sorgusunu takip etmeye etkili bir şekilde eşdeğer olacaktır -

SELECT students.id, 
   students.name, 
   students.lastname
FROM students
WHERE students.name = :name_1 
OR students.id < :id_1

Değişikliği yaptıktan ve yukarıdaki kodu çalıştırdıktan sonra, sonuç, OR durumuna düşen iki satır olacaktır -

[(1, 'Ravi', 'Kapoor'),
(2, 'Rajiv', 'Khanna')]

asc () işlevi

Artan bir ORDER BY yan tümcesi üretir. İşlev, işlevi bir parametre olarak uygulamak için sütunu alır.

from sqlalchemy import asc
stmt = select([students]).order_by(asc(students.c.name))

İfade aşağıdaki SQL ifadesini uygular -

SELECT students.id, 
   students.name, 
   students.lastname
FROM students 
ORDER BY students.name ASC

Aşağıdaki kod, öğrenciler tablosundaki tüm kayıtları ad sütununun artan sırasına göre listeler -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, ForeignKey, select
engine = create_engine('sqlite:///college.db', echo = True)
meta = MetaData()
conn = engine.connect()

students = Table(
   'students', meta, 
   Column('id', Integer, primary_key = True), 
   Column('name', String), 
   Column('lastname', String), 
)

from sqlalchemy import asc
stmt = select([students]).order_by(asc(students.c.name))
result = conn.execute(stmt)

for row in result:
   print (row)

Yukarıdaki kod aşağıdaki çıktıyı üretir -

(4, 'Abdul', 'Sattar')
(3, 'Komal', 'Bhandari')
(5, 'Priya', 'Rajhans')
(2, 'Rajiv', 'Khanna')
(1, 'Ravi', 'Kapoor')

desc () işlevi

Benzer şekilde desc () işlevi, aşağıdaki gibi azalan ORDER BY yan tümcesi üretir -

from sqlalchemy import desc
stmt = select([students]).order_by(desc(students.c.lastname))

Eşdeğer SQL ifadesi -

SELECT students.id, 
   students.name, 
   students.lastname
FROM students 
ORDER BY students.lastname DESC

Ve yukarıdaki kod satırlarının çıktısı -

(4, 'Abdul', 'Sattar')
(5, 'Priya', 'Rajhans')
(2, 'Rajiv', 'Khanna')
(1, 'Ravi', 'Kapoor')
(3, 'Komal', 'Bhandari')

arasında () işlevi

BETWEEN yüklem yan tümcesi üretir. Bu genellikle belirli bir sütunun değerinin bir aralık arasında olup olmadığını doğrulamak için kullanılır. Örneğin, aşağıdaki kod, id sütunu 2 ile 4 arasında olan satırları seçer -

from sqlalchemy import between
stmt = select([students]).where(between(students.c.id,2,4))
print (stmt)

Ortaya çıkan SQL ifadesi şuna benzer:

SELECT students.id, 
   students.name, 
   students.lastname
FROM students
WHERE students.id 
BETWEEN :id_1 AND :id_2

ve sonuç aşağıdaki gibidir -

(2, 'Rajiv', 'Khanna')
(3, 'Komal', 'Bhandari')
(4, 'Abdul', 'Sattar')

SQLAlchemy'de kullanılan bazı önemli işlevler bu bölümde tartışılmaktadır.

Standart SQL, çoğu lehçe tarafından uygulanan birçok işlevi önermiştir. Kendisine iletilen argümanlara göre tek bir değer döndürürler. Bazı SQL işlevleri sütunları bağımsız değişken olarak alırken bazıları geneldir.Thefunc keyword in SQLAlchemy API is used to generate these functions.

SQL'de artık () genel bir işlevdir. Aşağıdaki ifadeler now () işlevini func -

from sqlalchemy.sql import func
result = conn.execute(select([func.now()]))
print (result.fetchone())

Yukarıdaki kodun örnek sonucu aşağıda gösterildiği gibi olabilir -

(datetime.datetime(2018, 6, 16, 6, 4, 40),)

Öte yandan, bir tablodan seçilen satırların sayısını döndüren count () işlevi, func -

from sqlalchemy.sql import func
result = conn.execute(select([func.count(students.c.id)]))
print (result.fetchone())

Yukarıdaki koddan öğrenci tablosundaki satır sayısı getirilecektir.

Bazı yerleşik SQL işlevleri, aşağıdaki verilerle Çalışan tablosu kullanılarak gösterilir -

İD İsim İşaretler
1 Kamal 56
2 Fernandez 85
3 Sunil 62
4 Bhaskar 76

Max () işlevi, SQLAlchemy'den func kullanımı takip edilerek uygulanır ve bu da 85 ile sonuçlanır, toplam maksimum puan -

from sqlalchemy.sql import func
result = conn.execute(select([func.max(employee.c.marks)]))
print (result.fetchone())

Benzer şekilde, en az 56 işareti döndürecek min () işlevi aşağıdaki kodla oluşturulacaktır -

from sqlalchemy.sql import func
result = conn.execute(select([func.min(employee.c.marks)]))
print (result.fetchone())

Bu nedenle, AVG () işlevi aşağıdaki kod kullanılarak da uygulanabilir -

from sqlalchemy.sql import func
result = conn.execute(select([func.avg(employee.c.marks)]))
print (result.fetchone())

Functions are normally used in the columns clause of a select statement. 
They can also be given label as well as a type. A label to function allows the result 
to be targeted in a result row based on a string name, and a type is required when 
you need result-set processing to occur.from sqlalchemy.sql import func

result = conn.execute(select([func.max(students.c.lastname).label('Name')]))

print (result.fetchone())

Son bölümde max (), min (), count () vb. Gibi çeşitli fonksiyonlar hakkında bilgi edindik, burada set işlemlerini ve kullanımlarını öğreneceğiz.

UNION ve INTERSECT gibi set işlemleri, standart SQL ve lehçesinin çoğu tarafından desteklenir. SQLAlchemy bunları aşağıdaki işlevlerin yardımıyla uygular -

Birlik()

İki veya daha fazla SELECT ifadesinin sonuçlarını birleştirirken, UNION, sonuç kümesindeki kopyaları ortadan kaldırır. Her iki tabloda da sütun sayısı ve veri türü aynı olmalıdır.

Union () işlevi, birden çok tablodan bir CompoundSelect nesnesi döndürür. Aşağıdaki örnek, kullanımını göstermektedir -

from sqlalchemy import create_engine, MetaData, Table, Column, Integer, String, union
engine = create_engine('sqlite:///college.db', echo = True)

meta = MetaData()
conn = engine.connect()
addresses = Table(
   'addresses', meta, 
   Column('id', Integer, primary_key = True), 
   Column('st_id', Integer), 
   Column('postal_add', String), 
   Column('email_add', String)
)

u = union(addresses.select().where(addresses.c.email_add.like('%@gmail.com addresses.select().where(addresses.c.email_add.like('%@yahoo.com'))))

result = conn.execute(u)
result.fetchall()

Birleşim yapısı aşağıdaki SQL ifadesine çevrilir -

SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.email_add LIKE ? UNION SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.email_add LIKE ?

Adres tablomuzdan, aşağıdaki satırlar birleşim işlemini temsil eder -

[
   (1, 1, 'Shivajinagar Pune', '[email protected]'),
   (2, 1, 'ChurchGate Mumbai', '[email protected]'),
   (3, 3, 'Jubilee Hills Hyderabad', '[email protected]'),
   (4, 5, 'MG Road Bangaluru', '[email protected]')
]

union_all ()

UNION ALL işlemi yinelenenleri kaldıramaz ve sonuç kümesindeki verileri sıralayamaz. Örneğin, yukarıdaki sorguda UNION, etkisini görmek için UNION ALL ile değiştirilmiştir.

u = union_all(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.email_add.like('%@yahoo.com')))

Karşılık gelen SQL ifadesi aşağıdaki gibidir -

SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.email_add LIKE ? UNION ALL SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.email_add LIKE ?

dışında_()

SQL EXCEPTyan tümce / işleç, iki SELECT deyimini birleştirmek ve ilk SELECT deyiminden ikinci SELECT deyimi tarafından döndürülmeyen satırları döndürmek için kullanılır. Exclu_ () işlevi EXCEPT yan tümcesine sahip bir SELECT ifadesi oluşturur.

Aşağıdaki örnekte, exclu_ () işlevi, yalnızca e-posta_add alanında 'gmail.com' bulunan adres tablosundaki kayıtları döndürür, ancak postal_add alanının bir parçası olarak 'Pune' bulunanları hariç tutar.

u = except_(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.postal_add.like('%Pune')))

Yukarıdaki kodun sonucu aşağıdaki SQL ifadesidir -

SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.email_add LIKE ? EXCEPT SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.postal_add LIKE ?

Adres tablosunun önceki örneklerde kullanılan verileri içerdiğini varsayarsak, aşağıdaki çıktıyı gösterecektir -

[(2, 1, 'ChurchGate Mumbai', '[email protected]'),
   (3, 3, 'Jubilee Hills Hyderabad', '[email protected]')]

kesişmek ()

INTERSECT operatörünü kullanarak SQL, her iki SELECT deyiminden ortak satırları görüntüler. İntersect () işlevi bu davranışı uygular.

Aşağıdaki örneklerde, iki SELECT yapısı, intersect () işlevinin parametreleridir. Biri, email_add sütununun bir parçası olarak 'gmail.com'u içeren satırları döndürür ve diğerleri, postal_add sütununun bir parçası olarak' Pune 'içeren satırları döndürür. Sonuç, her iki sonuç kümesinden ortak satırlar olacaktır.

u = intersect(addresses.select().where(addresses.c.email_add.like('%@gmail.com')), addresses.select().where(addresses.c.postal_add.like('%Pune')))

Aslında bu, aşağıdaki SQL ifadesine eşdeğerdir -

SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.email_add LIKE ? INTERSECT SELECT addresses.id, 
   addresses.st_id, 
   addresses.postal_add, 
   addresses.email_add
FROM addresses
WHERE addresses.postal_add LIKE ?

İki bağlı parametre '% gmail.com' ve '% Pune', aşağıda gösterildiği gibi adres tablosundaki orijinal verilerden tek bir satır oluşturur -

[(1, 1, 'Shivajinagar Pune', '[email protected]')]

SQLAlchemy'nin Object Relational Mapper API'sinin temel amacı, kullanıcı tanımlı Python sınıflarını veritabanı tablolarıyla ve bu sınıfların nesnelerini karşılık gelen tablolardaki satırlarla ilişkilendirmeyi kolaylaştırmaktır. Nesnelerin ve satırların durumlarındaki değişiklikler birbiriyle eşzamanlı olarak eşleştirilir. SQLAlchemy, veritabanı sorgularının kullanıcı tanımlı sınıflar ve bunların tanımlanmış ilişkileri açısından ifade edilmesini sağlar.

ORM, SQL İfade Dili üzerine inşa edilmiştir. Yüksek seviyeli ve soyutlanmış bir kullanım şeklidir. Aslında ORM, İfade Dilinin uygulamalı bir kullanımıdır.

Başarılı bir uygulama yalnızca Nesne İlişkisel Eşleştiricisi kullanılarak oluşturulabilse de, bazen ORM ile oluşturulan bir uygulama, belirli veritabanı etkileşimlerinin gerekli olduğu durumlarda İfade Dilini doğrudan kullanabilir.

Eşleme Bildir

Her şeyden önce, daha sonra SQL işlemlerini gerçekleştirmek için kullanılacak bir motor nesnesi kurmak için create_engine () işlevi çağrılır. İşlevin iki bağımsız değişkeni vardır; biri veritabanının adıdır ve diğeri True olarak ayarlandığında etkinlik günlüğünü oluşturacak bir yankı parametresidir. Mevcut değilse, veritabanı oluşturulacaktır. Aşağıdaki örnekte, bir SQLite veritabanı oluşturulmuştur.

from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)

Engine, Engine.execute () veya Engine.connect () gibi bir yöntem çağrıldığında veritabanına gerçek bir DBAPI bağlantısı kurar. Daha sonra Motoru doğrudan kullanmayan SQLORM'yi yayınlamak için kullanılır; bunun yerine, ORM tarafından perde arkasında kullanılır.

ORM durumunda, konfigürasyon süreci veritabanı tablolarını açıklayarak ve ardından bu tablolara eşlenecek sınıfları tanımlayarak başlar. SQLAlchemy'de bu iki görev birlikte gerçekleştirilir. Bu, Bildirim sistemi kullanılarak yapılır; oluşturulan sınıflar, eşlendikleri gerçek veritabanı tablosunu tanımlayan yönergeleri içerir.

Temel sınıf, Bildirim sistemindeki sınıfların kataloğunu ve eşlenmiş tabloları depolar. Bu, bildirim temelli temel sınıf olarak adlandırılır. Yaygın olarak içe aktarılan bir modülde genellikle bu tabanın yalnızca bir örneği olacaktır. Declarative_base () işlevi temel sınıf oluşturmak için kullanılır. Bu fonksiyon sqlalchemy.ext.declarative modülünde tanımlanmıştır.

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

Temel sınıf bir kez bildirildikten sonra, herhangi bir sayıda eşlenmiş sınıf, onun açısından tanımlanabilir. Aşağıdaki kod, bir Müşterinin sınıfını tanımlar. Eşlenecek tabloyu ve içindeki sütunların adlarını ve veri türlerini içerir.

class Customers(Base):
   __tablename__ = 'customers'
   
   id = Column(Integer, primary_key = True)
   name = Column(String)
   address = Column(String)
   email = Column(String)

Bildirge'deki bir sınıfın bir __tablename__ öznitelik ve en az bir Columnbirincil anahtarın parçası olan. Bildirim, tümColumn olarak bilinen özel Python erişimcili nesneler descriptors. Bu işlem, bir SQL bağlamında tabloya başvurma araçları sağlayan ve veritabanından sütunların değerlerinin kalıcı olarak yüklenmesini ve yüklenmesini sağlayan araçlar olarak bilinir.

Normal bir Python sınıfı gibi bu eşlenmiş sınıf, gereksinime göre niteliklere ve yöntemlere sahiptir.

Bildirime dayalı sistemde sınıfla ilgili bilgiler tablo meta verileri olarak adlandırılır. SQLAlchemy, Declarative tarafından oluşturulan belirli bir tablo için bu bilgileri temsil etmek üzere Table nesnesini kullanır. Tablo nesnesi, belirtimlere göre oluşturulur ve bir Mapper nesnesi oluşturularak sınıfla ilişkilendirilir. Bu eşleyici nesne doğrudan kullanılmaz, ancak eşlenen sınıf ve tablo arasında arabirim olarak dahili olarak kullanılır.

Her bir Tablo nesnesi, MetaData olarak bilinen daha büyük bir koleksiyonun üyesidir ve bu nesne, .metadatabildirim temelli temel sınıfın özniteliği. MetaData.create_all()yöntem, bir veritabanı bağlantısı kaynağı olarak Motorumuza geçmektir. Henüz oluşturulmamış tüm tablolar için, CREATE TABLE deyimlerini veritabanına yayınlar.

Base.metadata.create_all(engine)

Bir veritabanı ve bir tablo oluşturmak ve Python sınıfını eşlemek için eksiksiz komut dosyası aşağıda verilmiştir -

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Customers(Base):
   __tablename__ = 'customers'
   id = Column(Integer, primary_key=True)

   name = Column(String)
   address = Column(String)
   email = Column(String)
Base.metadata.create_all(engine)

Çalıştırıldığında, Python konsolu çalıştırılan SQL ifadesinin ardından yankılanacaktır -

CREATE TABLE customers (
   id INTEGER NOT NULL,
   name VARCHAR,
   address VARCHAR,
   email VARCHAR,
   PRIMARY KEY (id)
)

Sales.db'yi SQLiteStudio grafik aracını kullanarak açarsak, yukarıda belirtilen yapıyla içindeki müşteri tablosunu gösterir.

Veritabanıyla etkileşim kurabilmek için onun işleyişini sağlamamız gerekir. Bir oturum nesnesi, veritabanının tutucusudur. Oturum sınıfı, daha önce oluşturulan motor nesnesine bağlı olan yapılandırılabilir bir oturum fabrikası yöntemi olan sessionmaker () kullanılarak tanımlanır.

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)

Oturum nesnesi daha sonra varsayılan yapıcısı kullanılarak aşağıdaki gibi ayarlanır -

session = Session()

Sıklıkla gerekli olan oturum sınıfı yöntemlerinden bazıları aşağıda listelenmiştir -

Sr.No. Yöntem ve Açıklama
1

begin()

bu oturumda bir işlem başlatır

2

add()

oturuma bir nesne yerleştirir. Durumu bir sonraki yıkama işleminde veritabanında kalır.

3

add_all()

oturuma bir nesne koleksiyonu ekler

4

commit()

tüm öğeleri ve devam eden herhangi bir işlemi temizler

5

delete()

bir işlemi silinmiş olarak işaretler

6

execute()

bir SQL ifadesi yürütür

7

expire()

bir örneğin niteliklerini güncel değil olarak işaretler

8

flush()

tüm nesne değişikliklerini veritabanına boşaltır

9

invalidate()

bağlantı geçersiz kılarak oturumu kapatır

10

rollback()

devam etmekte olan mevcut işlemi geri alır

11

close()

Tüm öğeleri temizleyerek ve devam eden herhangi bir işlemi sonlandırarak mevcut oturumu kapatır

SQLAlchemy ORM'nin önceki bölümlerinde, haritalamanın nasıl ilan edileceğini ve oturumların nasıl oluşturulacağını öğrendik. Bu bölümde, tabloya nasıl nesne ekleneceğini öğreneceğiz.

Müşteriler tablosu ile eşleştirilen Müşteri sınıfını beyan ettik. Bu sınıfın bir nesnesini bildirmeli ve bunu oturum nesnesinin add () yöntemiyle sürekli olarak tabloya eklemeliyiz.

c1 = Sales(name = 'Ravi Kumar', address = 'Station Road Nanded', email = '[email protected]')
session.add(c1)

Aynı işlem commit () yöntemi kullanılarak temizlenene kadar bu işlemin beklemede olduğunu unutmayın.

session.commit()

Aşağıda, müşteriler tablosuna bir kayıt eklemek için eksiksiz komut dosyası verilmiştir -

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Customers(Base):
   __tablename__ = 'customers'
   
   id = Column(Integer, primary_key=True)
   name = Column(String)
   address = Column(String)
   email = Column(String)
   
from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()

c1 = Customers(name = 'Ravi Kumar', address = 'Station Road Nanded', email = '[email protected]')

session.add(c1)
session.commit()

Birden fazla kayıt eklemek için kullanabiliriz add_all() oturum sınıfının yöntemi.

session.add_all([
   Customers(name = 'Komal Pande', address = 'Koti, Hyderabad', email = '[email protected]'), 
   Customers(name = 'Rajender Nath', address = 'Sector 40, Gurgaon', email = '[email protected]'), 
   Customers(name = 'S.M.Krishna', address = 'Budhwar Peth, Pune', email = '[email protected]')]
)

session.commit()

SQLiteStudio'nun tablo görünümü, kayıtların müşteriler tablosuna kalıcı olarak eklendiğini gösterir. Aşağıdaki görüntü sonucu gösterir -

SQLAlchemy ORM tarafından üretilen tüm SELECT ifadeleri Query nesnesi tarafından oluşturulur. Üretken bir arayüz sağlar, bu nedenle ardışık çağrılar yeni bir Sorgu nesnesi döndürür, eskisinin bir kopyası, ek kriterler ve kendisiyle ilişkili seçeneklerle birlikte.

Sorgu nesneleri başlangıçta aşağıdaki gibi Session'ın query () yöntemi kullanılarak oluşturulur -

q = session.query(mapped class)

Aşağıdaki ifade de yukarıda verilen ifadeye eşdeğerdir -

q = Query(mappedClass, session)

Sorgu nesnesi, nesnelerin listesi biçiminde bir sonuç kümesi döndüren all () yöntemine sahiptir. Bunu müşterilerimiz masasında yürütürsek -

result = session.query(Customers).all()

Bu ifade, aşağıdaki SQL ifadesine etkin bir şekilde eşdeğerdir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers

Sonuç nesnesi, temeldeki müşteriler tablosundaki tüm kayıtları elde etmek için aşağıdaki gibi For döngüsü kullanılarak gezilebilir. Müşteriler tablosundaki tüm kayıtları görüntülemek için tam kod:

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Customers(Base):
   __tablename__ = 'customers'
   id = Column(Integer, primary_key =  True)
   name = Column(String)

   address = Column(String)
   email = Column(String)

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
result = session.query(Customers).all()

for row in result:
   print ("Name: ",row.name, "Address:",row.address, "Email:",row.email)

Python konsolu, kayıtların listesini aşağıdaki gibi gösterir -

Name: Ravi Kumar Address: Station Road Nanded Email: [email protected]
Name: Komal Pande Address: Koti, Hyderabad Email: [email protected]
Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected]
Name: S.M.Krishna Address: Budhwar Peth, Pune Email: [email protected]

Sorgu nesnesi ayrıca aşağıdaki yararlı yöntemlere sahiptir:

Sr.No. Yöntem ve Açıklama
1

add_columns()

Döndürülecek sonuç sütunları listesine bir veya daha fazla sütun ifadesi ekler.

2

add_entity()

Döndürülecek sonuç sütunları listesine eşlenmiş bir varlık ekler.

3

count()

Bu Sorgunun döndüreceği bir satır sayısı döndürür.

4

delete()

Toplu silme sorgusu gerçekleştirir. Bu sorgu ile eşleşen satırları veritabanından siler.

5

distinct()

Sorguya DISTINCT yan tümcesi uygular ve yeni oluşan Sorguyu döndürür.

6

filter()

SQL ifadelerini kullanarak, verilen filtreleme kriterini bu Sorgunun bir kopyasına uygular.

7

first()

Bu Sorgunun ilk sonucunu veya sonuç herhangi bir satır içermiyorsa Hiçbirini döndürür.

8

get()

Sahip olan Oturumun kimlik haritasına doğrudan erişim sağlayan, verilen birincil anahtar tanımlayıcıya dayalı bir örnek döndürür.

9

group_by()

Sorguya bir veya daha fazla GROUP BY kriteri uygular ve yeni ortaya çıkan Sorguyu döndürür

10

join()

Bu Query nesnesinin kriterine karşı bir SQL JOIN oluşturur ve yeni oluşan Sorguyu döndürerek üretken olarak uygular.

11

one()

Tam olarak bir sonuç döndürür veya bir istisna oluşturur.

12

order_by()

Sorguya bir veya daha fazla ORDER BY ölçütü uygular ve yeni oluşan Sorguyu döndürür.

13

update()

Bir toplu güncelleme sorgusu gerçekleştirir ve veritabanında bu sorgu ile eşleşen satırları günceller.

Bu bölümde, tablonun istenen değerlerle nasıl değiştirileceğini veya güncelleneceğini göreceğiz.

Herhangi bir nesnenin belirli bir özelliğinin verilerini değiştirmek için, ona yeni bir değer atamalı ve değişikliği kalıcı hale getirmek için değişiklikleri uygulamalıyız.

Müşteriler tablomuzda ID = 2 ile birincil anahtar tanımlayıcısı olan tablodan bir nesne getirelim. Get () session yöntemini şu şekilde kullanabiliriz -

x = session.query(Customers).get(2)

Seçilen nesnenin içeriğini aşağıdaki kod ile görüntüleyebiliriz -

print ("Name: ", x.name, "Address:", x.address, "Email:", x.email)

Müşterilerimizin tablosundan aşağıdaki çıktı görüntülenmelidir -

Name: Komal Pande Address: Koti, Hyderabad Email: [email protected]

Şimdi, aşağıda verildiği gibi yeni bir değer atayarak Adres alanını güncellememiz gerekiyor -

x.address = 'Banjara Hills Secunderabad'
session.commit()

Değişiklik sürekli olarak veritabanına yansıtılacaktır. Şimdi tablodaki ilk satıra karşılık gelen nesneyi kullanarakfirst() method aşağıdaki gibi -

x = session.query(Customers).first()

Bu, aşağıdaki SQL ifadesini çalıştıracaktır -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
LIMIT ? OFFSET ?

Bağlı parametreler sırasıyla LIMIT = 1 ve OFFSET = 0 olacaktır, bu da ilk satırın seçileceği anlamına gelir.

print ("Name: ", x.name, "Address:", x.address, "Email:", x.email)

Şimdi, ilk satırı görüntüleyen yukarıdaki kodun çıktısı aşağıdaki gibidir -

Name: Ravi Kumar Address: Station Road Nanded Email: [email protected]

Şimdi ad özniteliğini değiştirin ve aşağıdaki kodu kullanarak içeriği görüntüleyin -

x.name = 'Ravi Shrivastava'
print ("Name: ", x.name, "Address:", x.address, "Email:", x.email)

Yukarıdaki kodun çıktısı -

Name: Ravi Shrivastava Address: Station Road Nanded Email: [email protected]

Değişiklik gösterilse bile taahhüt edilmemiştir. Kullanarak daha önceki kalıcı konumu koruyabilirsinizrollback() method aşağıdaki kod ile.

session.rollback()

print ("Name: ", x.name, "Address:", x.address, "Email:", x.email)

İlk kaydın orijinal içeriği görüntülenecektir.

Toplu güncellemeler için, Query nesnesinin update () yöntemini kullanacağız. Bir önek vermeyi deneyelim, 'Bay' her satıra isim vermek için (ID = 2 hariç). Karşılık gelen update () ifadesi aşağıdaki gibidir -

session.query(Customers).filter(Customers.id! = 2).
update({Customers.name:"Mr."+Customers.name}, synchronize_session = False)

The update() method requires two parameters as follows −

  • Anahtarın güncellenecek öznitelik olduğu ve değerin özniteliğin yeni içeriği olduğu bir anahtar / değer çiftleri sözlüğü.

  • Senkronize_session özelliği, oturumdaki öznitelikleri güncelleme stratejisinden bahseder. Geçerli değerler yanlıştır: oturumu senkronize etmemek için fetch: güncelleme sorgusuyla eşleşen nesneleri bulmak için güncellemeden önce bir seçme sorgusu gerçekleştirir; ve değerlendirin: oturumdaki nesneler üzerindeki kriterleri değerlendirin.

Tablodaki 4 satırdan üçünün önünde 'Bay' olan ada sahip olacaktır. Ancak, değişiklikler yapılmaz ve bu nedenle SQLiteStudio'nun tablo görünümüne yansıtılmaz. Yalnızca oturumu tamamladığımızda yenilenecektir.

Bu bölümde, filtrelerin nasıl uygulanacağını ve ayrıca kodlarıyla birlikte belirli filtre işlemlerini tartışacağız.

Sorgu nesnesi tarafından temsil edilen sonuç kümesi, filter () yöntemi kullanılarak belirli kriterlere tabi tutulabilir. Filtre yönteminin genel kullanımı aşağıdaki gibidir -

session.query(class).filter(criteria)

Aşağıdaki örnekte, Müşteriler tablosundaki SELECT sorgusu tarafından elde edilen sonuç kümesi bir koşula göre filtrelenmiştir, (ID> 2) -

result = session.query(Customers).filter(Customers.id>2)

Bu ifade aşağıdaki SQL ifadesine çevrilecektir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id > ?

Bağlı parametre (?) 2 olarak verildiğinden, sadece ID sütunu> 2 olan satırlar görüntülenecektir. Kodun tamamı aşağıda verilmiştir -

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()

class Customers(Base):
   __tablename__ = 'customers'
   
   id = Column(Integer, primary_key = True)
   name = Column(String)

   address = Column(String)
   email = Column(String)

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
result = session.query(Customers).filter(Customers.id>2)

for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

Python konsolunda görüntülenen çıktı aşağıdaki gibidir -

ID: 3 Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected]
ID: 4 Name: S.M.Krishna Address: Budhwar Peth, Pune Email: [email protected]

Şimdi filtre işlemlerini ilgili kodları ve çıktıları ile öğreneceğiz.

Eşittir

Kullanılan olağan operatör == ve eşitliği kontrol etmek için kriterleri uygular.

result = session.query(Customers).filter(Customers.id == 2)

for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

SQLAlchemy aşağıdaki SQL ifadesini gönderecek -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id = ?

Yukarıdaki kodun çıktısı aşağıdaki gibidir -

ID: 2 Name: Komal Pande Address: Banjara Hills Secunderabad Email: [email protected]

Eşit Değil

Eşit değil için kullanılan işleç! = 'Dir ve eşittir ölçütü sağlamaz.

result = session.query(Customers).filter(Customers.id! = 2)

for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

Ortaya çıkan SQL ifadesi -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id != ?

Yukarıdaki kod satırlarının çıktısı aşağıdaki gibidir -

ID: 1 Name: Ravi Kumar Address: Station Road Nanded Email: [email protected]
ID: 3 Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected]
ID: 4 Name: S.M.Krishna Address: Budhwar Peth, Pune Email: [email protected]

Sevmek

like () yönteminin kendisi, SELECT ifadesindeki WHERE yan tümcesi için LIKE ölçütlerini üretir.

result = session.query(Customers).filter(Customers.name.like('Ra%'))
for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

Yukarıdaki SQLAlchemy kodu aşağıdaki SQL ifadesine eşdeğerdir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.name LIKE ?

Ve yukarıdaki kodun çıktısı -

ID: 1 Name: Ravi Kumar Address: Station Road Nanded Email: [email protected]
ID: 3 Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected]

İÇİNDE

Bu operatör, sütun değerinin bir listedeki öğeler koleksiyonuna ait olup olmadığını kontrol eder. İn_ () yöntemi ile sağlanır.

result = session.query(Customers).filter(Customers.id.in_([1,3]))
for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

Burada SQLite motoru tarafından değerlendirilen SQL ifadesi aşağıdaki gibi olacaktır -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id IN (?, ?)

Yukarıdaki kodun çıktısı aşağıdaki gibidir -

ID: 1 Name: Ravi Kumar Address: Station Road Nanded Email: [email protected]
ID: 3 Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected]

VE

Bu bağlaç biri tarafından oluşturulur putting multiple commas separated criteria in the filter or using and_() method aşağıda verildiği gibi -

result = session.query(Customers).filter(Customers.id>2, Customers.name.like('Ra%'))
for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

from sqlalchemy import and_
result = session.query(Customers).filter(and_(Customers.id>2, Customers.name.like('Ra%')))

for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

Yukarıdaki yaklaşımların her ikisi de benzer SQL ifadesiyle sonuçlanır -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id > ? AND customers.name LIKE ?

Yukarıdaki kod satırları için çıktı -

ID: 3 Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected]

VEYA

Bu bağlaç, or_() method.

from sqlalchemy import or_
result = session.query(Customers).filter(or_(Customers.id>2, Customers.name.like('Ra%')))

for row in result:
   print ("ID:", row.id, "Name: ",row.name, "Address:",row.address, "Email:",row.email)

Sonuç olarak, SQLite motoru aşağıdaki eşdeğer SQL ifadesini alır -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id > ? OR customers.name LIKE ?

Yukarıdaki kodun çıktısı aşağıdaki gibidir -

ID: 1 Name: Ravi Kumar Address: Station Road Nanded Email: [email protected]
ID: 3 Name: Rajender Nath Address: Sector 40, Gurgaon Email: [email protected]
ID: 4 Name: S.M.Krishna Address: Budhwar Peth, Pune Email: [email protected]

SQL'i hemen veren ve yüklenen veritabanı sonuçlarını içeren bir değer döndüren bir dizi Query nesnesi yöntemi vardır.

İşte geri dönen liste ve skalerlerin kısa bir özeti -

herşey()

Bir liste döndürür. Aşağıda all () işlevi için kod satırı verilmiştir.

session.query(Customers).all()

Python konsolu, yayılan aşağıdaki SQL ifadesini görüntüler -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers

ilk()

Bir limit uygular ve ilk sonucu skaler olarak döndürür.

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
LIMIT ? OFFSET ?

LİMİT için bağlı parametreler 1 ve OFSET için 0'dır.

bir()

Bu komut, tüm satırları tam olarak getirir ve sonuçta tam olarak bir nesne kimliği veya bileşik satır yoksa, bir hata oluşturur.

session.query(Customers).one()

Birden çok satır bulundu -

MultipleResultsFound: Multiple rows were found for one()

Hiçbir satır bulunamadı -

NoResultFound: No row was found for one()

One () yöntemi, "hiçbir öğe bulunamadı" yerine "birden çok öğe bulunamadı" durumunu farklı şekilde işlemeyi bekleyen sistemler için kullanışlıdır.

skaler ()

One () yöntemini çağırır ve başarı üzerine aşağıdaki gibi satırın ilk sütununu döndürür -

session.query(Customers).filter(Customers.id == 3).scalar()

Bu, aşağıdaki SQL ifadesini oluşturur -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id = ?

Daha önce, text () işlevini kullanan metinsel SQL, SQLAlchemy'nin çekirdek ifade dili perspektifinden açıklanmıştı. Şimdi bunu ORM açısından tartışacağız.

Değişmez dizeler, kullanımları text () yapısıyla belirtilerek Query nesnesiyle esnek bir şekilde kullanılabilir. Çoğu uygulanabilir yöntem bunu kabul eder. Örneğin, filter () ve order_by ().

Aşağıda verilen örnekte, filter () yöntemi "id <3" dizesini WHERE id <3'e çevirir

from sqlalchemy import text
for cust in session.query(Customers).filter(text("id<3")):
   print(cust.name)

Oluşturulan ham SQL ifadesi, filtrenin aşağıda gösterilen kodla WHERE yan tümcesine dönüştürülmesini gösterir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE id<3

Müşteriler tablosundaki örnek verilerimizden iki satır seçilecek ve isim sütunu aşağıdaki gibi yazdırılacaktır -

Ravi Kumar
Komal Pande

Dize tabanlı SQL ile bağlama parametrelerini belirtmek için iki nokta üst üste kullanın ve değerleri belirtmek için params () yöntemini kullanın.

cust = session.query(Customers).filter(text("id = :value")).params(value = 1).one()

Python konsolunda görüntülenen etkili SQL aşağıda verildiği gibi olacaktır -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE id = ?

Tamamen dizge tabanlı bir ifade kullanmak için, tam bir ifadeyi temsil eden bir text () yapısı from_statement () öğesine iletilebilir.

session.query(Customers).from_statement(text("SELECT * FROM customers")).all()

Yukarıdaki kodun sonucu, aşağıda verildiği gibi temel bir SELECT ifadesi olacaktır -

SELECT * FROM customers

Açıkçası, müşteriler tablosundaki tüm kayıtlar seçilecektir.

Text () yapısı, metinsel SQL'ini konumsal olarak Core veya ORM-eşlemeli sütun ifadelerine bağlamamızı sağlar. Bunu, TextClause.columns () yöntemine konumsal argümanlar olarak sütun ifadelerini ileterek başarabiliriz.

stmt = text("SELECT name, id, name, address, email FROM customers")
stmt = stmt.columns(Customers.id, Customers.name)
session.query(Customers.id, Customers.name).from_statement(stmt).all()

SQLite motoru, yukarıdaki kod tarafından oluşturulan aşağıdaki ifadeyi çalıştırsa bile, tüm satırların id ve name sütunları seçilecektir, text () yöntemindeki tüm sütunlar -

SELECT name, id, name, address, email FROM customers

Bu oturum, veritabanımızda zaten var olan bir tabloyla ilgili başka bir tablonun oluşturulmasını açıklar. Müşteriler tablosu müşterilerin ana verilerini içerir. Şimdi, bir müşteriye ait herhangi bir sayıda faturayı içerebilecek faturalar tablosu oluşturmamız gerekiyor. Bu, birden çok ilişkiye dair bir durumdur.

Bildirime dayalı kullanarak, bu tabloyu eşlenen sınıfı olan Faturalar ile birlikte aşağıda verildiği gibi tanımlarız -

from sqlalchemy import create_engine, ForeignKey, Column, Integer, String
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy.orm import relationship

class Customer(Base):
   __tablename__ = 'customers'

   id = Column(Integer, primary_key = True)
   name = Column(String)
   address = Column(String)
   email = Column(String)

class Invoice(Base):
   __tablename__ = 'invoices'
   
   id = Column(Integer, primary_key = True)
   custid = Column(Integer, ForeignKey('customers.id'))
   invno = Column(Integer)
   amount = Column(Integer)
   customer = relationship("Customer", back_populates = "invoices")

Customer.invoices = relationship("Invoice", order_by = Invoice.id, back_populates = "customer")
Base.metadata.create_all(engine)

Bu, aşağıdaki gibi SQLite motoruna CREATE TABLE sorgusu gönderecektir -

CREATE TABLE invoices (
   id INTEGER NOT NULL,
   custid INTEGER,
   invno INTEGER,
   amount INTEGER,
   PRIMARY KEY (id),
   FOREIGN KEY(custid) REFERENCES customers (id)
)

Sales.db'de SQLiteStudio aracı yardımıyla yeni tablonun oluşturulduğunu kontrol edebiliriz.

Invoices sınıfı, custid özniteliğine ForeignKey yapısını uygular. Bu yönerge, bu sütundaki değerlerin, müşteriler tablosundaki id sütununda bulunan değerler olarak sınırlandırılması gerektiğini belirtir. Bu, ilişkisel veritabanlarının temel bir özelliğidir ve bağlantısız tablo koleksiyonunu zengin örtüşen ilişkilere sahip olacak şekilde dönüştüren "yapıştırıcıdır".

İlişki () olarak bilinen ikinci bir yönerge, ORM'ye Invoice sınıfının Invoice.customer özelliği kullanılarak Müşteri sınıfına bağlanması gerektiğini söyler. İlişki (), bu bağlantının doğasını belirlemek için iki tablo arasındaki yabancı anahtar ilişkilerini kullanır ve çoktan bire olduğunu belirler.

Customer.invoices özelliği altında Müşteri eşlenen sınıfına ek bir ilişki () yönergesi yerleştirilir. İlişki.back_populates parametresi, tamamlayıcı öznitelik adlarına başvurmak üzere atanır, böylece her bir ilişki (), ters olarak ifade edilen aynı ilişki hakkında akıllı kararlar verebilir. Bir tarafta Invoices.customer, Invoices örneğini, diğer tarafta Customer.invoices, Müşteri örneklerinin bir listesini ifade eder.

İlişki işlevi, SQLAlchemy ORM paketinin İlişki API'sinin bir parçasıdır. İki eşlenmiş sınıf arasında bir ilişki sağlar. Bu, bir ebeveyn-çocuk veya ilişkisel tablo ilişkisine karşılık gelir.

Bulunan temel İlişki Modelleri aşağıdadır -

Birden çoğa

Bire Çok ilişkisi, alt tablodaki yabancı anahtar yardımıyla ebeveyne atıfta bulunur. ilişki (), alt öğe tarafından temsil edilen bir öğe koleksiyonuna referans olarak üstte belirtilir. Communication.back_populates parametresi, "ters" tarafın çoka bir olduğu bire çokta çift yönlü bir ilişki kurmak için kullanılır.

Çoktan bire

Öte yandan, Çoktan Bire ilişkisi, çocuğa başvurmak için ana tabloya bir yabancı anahtar yerleştirir. ilişki (), yeni bir skaler tutma özniteliğinin oluşturulacağı üst öğe üzerinde bildirilir. Burada yine Bidirectionalbehaviour için communication.back_populates parametresi kullanılır.

Bire bir

Bire Bir ilişki, esasen doğada çift yönlü bir ilişkidir. Uselist bayrağı, ilişkinin "çok" tarafındaki bir koleksiyon yerine skaler bir özniteliğin yerleşimini belirtir. Birden çoka bire bir ilişki türüne dönüştürmek için uselist parametresini false olarak ayarlayın.

Çoktan çoğa

Çoktan çoğa ilişkisi, yabancı anahtarları ile öznitelikleri tanımlayarak iki sınıfla ilgili bir ilişki tablosu eklenerek kurulur. İlişki () için ikincil argüman ile belirtilir. Tablo genellikle bildirim temelli temel sınıfla ilişkili MetaData nesnesini kullanır, böylece ForeignKey yönergeleri bağlanacak uzak tabloları bulabilir. İlişki.back_populates parametresi, her ilişki () için çift yönlü bir ilişki kurar. İlişkinin her iki tarafı da bir koleksiyon içerir.

Bu bölümde, SQLAlchemy ORM'deki ilgili nesnelere odaklanacağız.

Şimdi bir Müşteri nesnesi oluşturduğumuzda, Python Listesi şeklinde boş bir fatura koleksiyonu bulunacaktır.

c1 = Customer(name = "Gopal Krishna", address = "Bank Street Hydarebad", email = "[email protected]")

C1.invoices'ın faturalar özelliği boş bir liste olacaktır. Listedeki öğeleri şu şekilde atayabiliriz -

c1.invoices = [Invoice(invno = 10, amount = 15000), Invoice(invno = 14, amount = 3850)]

Bu nesneyi Session nesnesini kullanarak veritabanına aşağıdaki gibi işleyelim -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
session.add(c1)
session.commit()

Bu, müşteriler ve fatura tabloları için otomatik olarak INSERT sorguları oluşturacaktır -

INSERT INTO customers (name, address, email) VALUES (?, ?, ?) 
('Gopal Krishna', 'Bank Street Hydarebad', '[email protected]')
INSERT INTO invoices (custid, invno, amount) VALUES (?, ?, ?)
(2, 10, 15000)
INSERT INTO invoices (custid, invno, amount) VALUES (?, ?, ?)
(2, 14, 3850)

Şimdi SQLiteStudio'nun tablo görünümündeki müşteri tablosu ve faturalar tablosunun içeriğine bakalım -

Aşağıdaki komutu kullanarak yapıcının kendisinde faturaların eşlenmiş özniteliğini sağlayarak Müşteri nesnesi oluşturabilirsiniz -

c2 = [
   Customer(
      name = "Govind Pant", 
      address = "Gulmandi Aurangabad",
      email = "[email protected]",
      invoices = [Invoice(invno = 3, amount = 10000), 
      Invoice(invno = 4, amount = 5000)]
   )
]

Veya aşağıda gösterildiği gibi oturum nesnesinin add_all () işlevi kullanılarak eklenecek nesnelerin bir listesi -

rows = [
   Customer(
      name = "Govind Kala", 
      address = "Gulmandi Aurangabad", 
      email = "[email protected]", 
      invoices = [Invoice(invno = 7, amount = 12000), Invoice(invno = 8, amount = 18500)]),

   Customer(
      name = "Abdul Rahman", 
      address = "Rohtak", 
      email = "[email protected]",
      invoices = [Invoice(invno = 9, amount = 15000), 
      Invoice(invno = 11, amount = 6000)
   ])
]

session.add_all(rows)
session.commit()

Artık iki tablonuz olduğuna göre, her iki tabloda da aynı anda nasıl sorgu oluşturacağımızı göreceğiz. Müşteri ve Fatura arasında basit bir örtük birleştirme oluşturmak için, Query.filter () kullanarak ilgili sütunları birbirine eşitleyebiliriz. Aşağıda, bu yöntemi kullanarak Müşteri ve Fatura varlıklarını tek seferde yüklüyoruz -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()

for c, i in session.query(Customer, Invoice).filter(Customer.id == Invoice.custid).all():
   print ("ID: {} Name: {} Invoice No: {} Amount: {}".format(c.id,c.name, i.invno, i.amount))

SQLAlchemy tarafından yayınlanan SQL ifadesi aşağıdaki gibidir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email, invoices.id 
AS invoices_id, invoices.custid 
AS invoices_custid, invoices.invno 
AS invoices_invno, invoices.amount 
AS invoices_amount
FROM customers, invoices
WHERE customers.id = invoices.custid

Ve yukarıdaki kod satırlarının sonucu aşağıdaki gibidir -

ID: 2 Name: Gopal Krishna Invoice No: 10 Amount: 15000
ID: 2 Name: Gopal Krishna Invoice No: 14 Amount: 3850
ID: 3 Name: Govind Pant Invoice No: 3 Amount: 10000
ID: 3 Name: Govind Pant Invoice No: 4 Amount: 5000
ID: 4 Name: Govind Kala Invoice No: 7 Amount: 12000
ID: 4 Name: Govind Kala Invoice No: 8 Amount: 8500
ID: 5 Name: Abdul Rahman Invoice No: 9 Amount: 15000
ID: 5 Name: Abdul Rahman Invoice No: 11 Amount: 6000

Gerçek SQL JOIN sözdizimi, Query.join () yöntemi kullanılarak aşağıdaki gibi kolayca elde edilir -

session.query(Customer).join(Invoice).filter(Invoice.amount == 8500).all()

Birleştirme için SQL ifadesi konsolda görüntülenecektir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers JOIN invoices ON customers.id = invoices.custid
WHERE invoices.amount = ?

For döngüsünü kullanarak sonucu yineleyebiliriz -

result = session.query(Customer).join(Invoice).filter(Invoice.amount == 8500)
for row in result:
   for inv in row.invoices:
      print (row.id, row.name, inv.invno, inv.amount)

Bağlama parametresi olarak 8500 ile aşağıdaki çıktı görüntülenir -

4 Govind Kala 8 8500

Query.join () bu tablolar arasında nasıl birleştirileceğini bilir çünkü aralarında yalnızca bir yabancı anahtar vardır. Yabancı anahtar veya daha fazla yabancı anahtar yoksa, Query.join () aşağıdaki formlardan biri kullanıldığında daha iyi çalışır -

query.join (Fatura, id == Adres.custid) açık durum
query.join (Customer.invoices) soldan sağa ilişkiyi belirtin
query.join (Invoice, Customer.invoices) aynı, açık hedefle
query.join ('faturalar') aynı, bir dize kullanarak

Benzer şekilde outerjoin () işlevi, sol dış birleşimi elde etmek için kullanılabilir.

query.outerjoin(Customer.invoices)

Subquery () yöntemi, bir takma ada gömülü SELECT ifadesini temsil eden bir SQL ifadesi üretir.

from sqlalchemy.sql import func

stmt = session.query(
   Invoice.custid, func.count('*').label('invoice_count')
).group_by(Invoice.custid).subquery()

Stmt nesnesi aşağıdaki gibi bir SQL ifadesi içerecektir -

SELECT invoices.custid, count(:count_1) AS invoice_count FROM invoices GROUP BY invoices.custid

İfademizi aldığımızda, bir Tablo yapısı gibi davranır. İfadedeki sütunlara, aşağıdaki kodda gösterildiği gibi c adı verilen bir öznitelik aracılığıyla erişilebilir -

for u, count in session.query(Customer, stmt.c.invoice_count).outerjoin(stmt, Customer.id == stmt.c.custid).order_by(Customer.id):
   print(u.name, count)

Yukarıdaki for döngüsü, aşağıdaki gibi fatura adlarına göre sayısını gösterir -

Arjun Pandit None
Gopal Krishna 2
Govind Pant 2
Govind Kala 2
Abdul Rahman 2

Bu bölümde, ilişkiler üzerine inşa edilen operatörler hakkında tartışacağız.

__eq __ ()

Yukarıdaki operatör çoka bir "eşittir" karşılaştırmasıdır. Bu operatörün kod satırı aşağıda gösterildiği gibidir -

s = session.query(Customer).filter(Invoice.invno.__eq__(12))

Yukarıdaki kod satırı için eşdeğer SQL sorgusu -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers, invoices
WHERE invoices.invno = ?

__ne __ ()

Bu operatör çoka bir "eşit değildir" karşılaştırmasıdır. Bu operatörün kod satırı aşağıda gösterildiği gibidir -

s = session.query(Customer).filter(Invoice.custid.__ne__(2))

Yukarıdaki kod satırı için eşdeğer SQL sorgusu aşağıda verilmiştir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers, invoices
WHERE invoices.custid != ?

içerir ()

Bu operatör, birden çoğa koleksiyonlar için kullanılır ve aşağıda contains () - için kod verilmiştir.

s = session.query(Invoice).filter(Invoice.invno.contains([3,4,5]))

Yukarıdaki kod satırı için eşdeğer SQL sorgusu -

SELECT invoices.id 
AS invoices_id, invoices.custid 
AS invoices_custid, invoices.invno 
AS invoices_invno, invoices.amount 
AS invoices_amount
FROM invoices
WHERE (invoices.invno LIKE '%' + ? || '%')

hiç()

herhangi bir () operatörü, aşağıda gösterildiği gibi koleksiyonlar için kullanılır -

s = session.query(Customer).filter(Customer.invoices.any(Invoice.invno==11))

Yukarıdaki kod satırı için eşdeğer SQL sorgusu aşağıda gösterilmiştir -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE EXISTS (
   SELECT 1
   FROM invoices
   WHERE customers.id = invoices.custid 
   AND invoices.invno = ?)

vardır()

Bu operatör skaler referanslar için aşağıdaki gibi kullanılır -

s = session.query(Invoice).filter(Invoice.customer.has(name = 'Arjun Pandit'))

Yukarıdaki kod satırı için eşdeğer SQL sorgusu -

SELECT invoices.id 
AS invoices_id, invoices.custid 
AS invoices_custid, invoices.invno 
AS invoices_invno, invoices.amount 
AS invoices_amount
FROM invoices
WHERE EXISTS (
   SELECT 1
   FROM customers
   WHERE customers.id = invoices.custid 
   AND customers.name = ?)

Yoğun yük, sorgu sayısını azaltır. SQLAlchemy, Sorguya ek talimatlar veren sorgu seçenekleri aracılığıyla başlatılan istekli yükleme işlevleri sunar. Bu seçenekler, Query.options () yöntemi aracılığıyla çeşitli özniteliklerin nasıl yükleneceğini belirler.

Alt Sorgu Yükü

Müşteri faturalarının hevesle yüklenmesini istiyoruz. Orm.subqueryload () seçeneği, yeni yüklenen sonuçlarla ilişkili koleksiyonları tam olarak yükleyen ikinci bir SELECT deyimi verir. "Alt sorgu" adı, SELECT ifadesinin doğrudan Sorgu aracılığıyla yeniden yapılandırılmasına ve ilgili tabloya karşı bir SELECT'e alt sorgu olarak gömülmesine neden olur.

from sqlalchemy.orm import subqueryload
c1 = session.query(Customer).options(subqueryload(Customer.invoices)).filter_by(name = 'Govind Pant').one()

Bu, aşağıdaki iki SQL ifadesine neden olur -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.name = ?
('Govind Pant',)

SELECT invoices.id 
AS invoices_id, invoices.custid 
AS invoices_custid, invoices.invno 
AS invoices_invno, invoices.amount 
AS invoices_amount, anon_1.customers_id 
AS anon_1_customers_id
FROM (
   SELECT customers.id 
   AS customers_id
   FROM customers
   WHERE customers.name = ?) 
   
AS anon_1 
JOIN invoices 
ON anon_1.customers_id = invoices.custid 
ORDER BY anon_1.customers_id, invoices.id 2018-06-25 18:24:47,479 
INFO sqlalchemy.engine.base.Engine ('Govind Pant',)

Verilere iki tablodan erişmek için aşağıdaki programı kullanabiliriz -

print (c1.name, c1.address, c1.email)

for x in c1.invoices:
   print ("Invoice no : {}, Amount : {}".format(x.invno, x.amount))

Yukarıdaki programın çıktısı aşağıdaki gibidir -

Govind Pant Gulmandi Aurangabad [email protected]
Invoice no : 3, Amount : 10000
Invoice no : 4, Amount : 5000

Birleştirilmiş Yük

Diğer işleve orm.joinedload () adı verilir. Bu, LEFT OUTER JOIN yayar. Müşteri adayı nesnesi ve ilgili nesne veya koleksiyon tek adımda yüklenir.

from sqlalchemy.orm import joinedload
c1 = session.query(Customer).options(joinedload(Customer.invoices)).filter_by(name='Govind Pant').one()

Bu, yukarıdaki ile aynı çıktıyı veren aşağıdaki ifadeyi yayar -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email, invoices_1.id 
AS invoices_1_id, invoices_1.custid 
AS invoices_1_custid, invoices_1.invno 
AS invoices_1_invno, invoices_1.amount 
AS invoices_1_amount

FROM customers 
LEFT OUTER JOIN invoices 
AS invoices_1 
ON customers.id = invoices_1.custid

WHERE customers.name = ? ORDER BY invoices_1.id
('Govind Pant',)

OUTER JOIN iki satırla sonuçlandı, ancak Müşterinin bir örneğini geri veriyor. Bunun nedeni, Sorgunun, döndürülen varlıklara nesne kimliğine dayalı bir "benzersizleştirme" stratejisi uygulamasıdır. Birleştirilmiş istekli yükleme, sorgu sonuçlarını etkilemeden uygulanabilir.

Subqueryload (), ilgili koleksiyonları yüklemek için daha uygunken, joinload () çoktan bire ilişki için daha uygundur.

Tek bir tablo üzerinde silme işlemi yapmak kolaydır. Tek yapmanız gereken, eşlenen sınıfın bir nesnesini bir oturumdan silmek ve eylemi uygulamaktır. Ancak, birden çok ilişkili tablodaki silme işlemi biraz karmaşıktır.

Sales.db veritabanımızda Müşteri ve Fatura sınıfları, müşteri ve fatura tablosu ile bire çok ilişki türü ile eşleştirilir. Müşteri nesnesini silmeye ve sonucu görmeye çalışacağız.

Hızlı bir referans olarak, Müşteri ve Fatura sınıflarının tanımları aşağıdadır -

from sqlalchemy import create_engine, ForeignKey, Column, Integer, String
engine = create_engine('sqlite:///sales.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy.orm import relationship
class Customer(Base):
   __tablename__ = 'customers'

   id = Column(Integer, primary_key = True)
   name = Column(String)
   address = Column(String)
   email = Column(String)
   
class Invoice(Base):
   __tablename__ = 'invoices'

   id = Column(Integer, primary_key = True)
   custid = Column(Integer, ForeignKey('customers.id'))
   invno = Column(Integer)
   amount = Column(Integer)
   customer = relationship("Customer", back_populates = "invoices")
   
Customer.invoices = relationship("Invoice", order_by = Invoice.id, back_populates = "customer")

Bir oturum kurarız ve aşağıdaki programı kullanarak birincil kimlik ile sorgulayarak bir Müşteri nesnesi elde ederiz -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind=engine)
session = Session()
x = session.query(Customer).get(2)

Örnek tablomuzda, x.name 'Gopal Krishna' olur. Bu x'i oturumdan silelim ve bu ismin oluşumunu sayalım.

session.delete(x)
session.query(Customer).filter_by(name = 'Gopal Krishna').count()

Ortaya çıkan SQL ifadesi 0 döndürür.

SELECT count(*) 
AS count_1
FROM (
   SELECT customers.id 
   AS customers_id, customers.name 
   AS customers_name, customers.address 
   AS customers_address, customers.email 
   AS customers_email
   FROM customers
   WHERE customers.name = ?) 
AS anon_1('Gopal Krishna',) 0

Ancak, x'in ilgili Fatura nesneleri hala oradadır. Aşağıdaki kodla doğrulanabilir -

session.query(Invoice).filter(Invoice.invno.in_([10,14])).count()

Burada 10 ve 14, müşteri Gopal Krishna'ya ait fatura numaralarıdır. Yukarıdaki sorgunun sonucu 2'dir, bu da ilgili nesnelerin silinmediği anlamına gelir.

SELECT count(*) 
AS count_1
FROM (
   SELECT invoices.id 
   AS invoices_id, invoices.custid 
   AS invoices_custid, invoices.invno 
   AS invoices_invno, invoices.amount 
   AS invoices_amount
   FROM invoices
   WHERE invoices.invno IN (?, ?)) 
AS anon_1(10, 14) 2

Bunun nedeni, SQLAlchemy'nin kademeli silme işlemini üstlenmemesidir; onu silmek için bir komut vermeliyiz.

Davranışı değiştirmek için, User.addresses ilişkisinde kademeli seçenekleri yapılandırıyoruz. Devam eden oturumu kapatalım, new declarative_base () kullanalım ve kademeli konfigürasyon dahil adres ilişkisini ekleyerek User sınıfını yeniden bildirelim.

İlişki işlevindeki basamaklı özniteliği, Oturum işlemlerinin ebeveynden alt öğeye nasıl "basamaklandırılması" gerektiğini belirleyen, virgülle ayrılmış bir basamaklı kurallar listesidir. Varsayılan olarak, False, yani "kaydet-güncelle, birleştir" anlamına gelir.

Mevcut kademeler aşağıdaki gibidir -

  • save-update
  • merge
  • expunge
  • delete
  • delete-orphan
  • refresh-expire

Sıklıkla kullanılan seçenek "all, delete-orphan" şeklindedir ve ilgili nesnelerin her durumda üst nesneyle birlikte takip etmesi ve ilişkisi kaldırıldığında silinmesi gerektiğini belirtir.

Bu nedenle, yeniden beyan edilen Müşteri sınıfı aşağıda gösterilmiştir -

class Customer(Base): 
   __tablename__ = 'customers'
   
   id = Column(Integer, primary_key = True) 
   name = Column(String) 
   address = Column(String) 
   email = Column(String) 
   invoices = relationship(
      "Invoice", 
      order_by = Invoice.id, 
      back_populates = "customer",
      cascade = "all, 
      delete, delete-orphan" 
   )

Aşağıdaki programı kullanarak Gopal Krishna adına sahip Müşteriyi silelim ve ilgili Fatura nesnelerinin sayısını görelim -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
x = session.query(Customer).get(2)
session.delete(x)
session.query(Customer).filter_by(name = 'Gopal Krishna').count()
session.query(Invoice).filter(Invoice.invno.in_([10,14])).count()

Yukarıdaki komut dosyası tarafından yayınlanan aşağıdaki SQL ile sayı artık 0'dır -

SELECT customers.id 
AS customers_id, customers.name 
AS customers_name, customers.address 
AS customers_address, customers.email 
AS customers_email
FROM customers
WHERE customers.id = ?
(2,)
SELECT invoices.id 
AS invoices_id, invoices.custid 
AS invoices_custid, invoices.invno 
AS invoices_invno, invoices.amount
AS invoices_amount
FROM invoices
WHERE ? = invoices.custid 
ORDER BY invoices.id (2,)
DELETE FROM invoices 
WHERE invoices.id = ? ((1,), (2,))
DELETE FROM customers 
WHERE customers.id = ? (2,)
SELECT count(*) 
AS count_1
FROM (
   SELECT customers.id 
   AS customers_id, customers.name 
   AS customers_name, customers.address 
   AS customers_address, customers.email 
   AS customers_email
   FROM customers
   WHERE customers.name = ?) 
AS anon_1('Gopal Krishna',)
SELECT count(*) 
AS count_1
FROM (
   SELECT invoices.id 
   AS invoices_id, invoices.custid 
   AS invoices_custid, invoices.invno 
   AS invoices_invno, invoices.amount 
   AS invoices_amount
   FROM invoices
   WHERE invoices.invno IN (?, ?)) 
AS anon_1(10, 14)
0

Many to Many relationshipiki tablo arasında, her tablonun birincil anahtarından bir tane olmak üzere iki yabancı anahtara sahip olacak şekilde bir ilişkilendirme tablosu eklenerek elde edilir. Ayrıca, iki tabloya eşlenen sınıflar, diğer ilişki tablolarının nesnelerinin bir koleksiyonunu, ilişkinin ikincil özniteliği () işlevi olarak atanan bir özniteliğe sahiptir.

Bu amaçla, departman ve çalışan olmak üzere iki tablo içeren bir SQLite veritabanı (mycollege.db) oluşturacağız. Burada, bir çalışanın birden fazla departmanın parçası olduğunu ve bir departmanın birden fazla çalışanı olduğunu varsayıyoruz. Bu, çoktan çoğa bir ilişki oluşturur.

Departman ve çalışan tablosuna eşlenen Çalışan ve Departman sınıflarının tanımı aşağıdaki gibidir -

from sqlalchemy import create_engine, ForeignKey, Column, Integer, String
engine = create_engine('sqlite:///mycollege.db', echo = True)
from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base()
from sqlalchemy.orm import relationship

class Department(Base):
   __tablename__ = 'department'
   id = Column(Integer, primary_key = True)
   name = Column(String)
   employees = relationship('Employee', secondary = 'link')
   
class Employee(Base):
   __tablename__ = 'employee'
   id = Column(Integer, primary_key = True)
   name = Column(String)
   departments = relationship(Department,secondary='link')

Şimdi bir Link sınıfı tanımlıyoruz. Bağlantı tablosuna bağlıdır ve sırasıyla departman ve çalışan tablosunun birincil anahtarlarına atıfta bulunan departman_id ve çalışan_kimliği özniteliklerini içerir.

class Link(Base):
   __tablename__ = 'link'
   department_id = Column(
      Integer, 
      ForeignKey('department.id'), 
      primary_key = True)

employee_id = Column(
   Integer, 
   ForeignKey('employee.id'), 
   primary_key = True)

Burada, Departman sınıfının Çalışan sınıfıyla ilgili çalışan özniteliğine sahip olduğunu not etmeliyiz. İlişki fonksiyonunun ikincil niteliğine, değeri olarak bir bağlantı atanır.

Benzer şekilde, Çalışan sınıfı, Departman sınıfıyla ilgili departments özniteliğine sahiptir. İlişki fonksiyonunun ikincil niteliğine, değeri olarak bir bağlantı atanır.

Aşağıdaki ifade yürütüldüğünde bu üç tablonun tümü oluşturulur -

Base.metadata.create_all(engine)

Python konsolu, aşağıdaki CREATE TABLE sorgularını yayınlar -

CREATE TABLE department (
   id INTEGER NOT NULL,
   name VARCHAR,
   PRIMARY KEY (id)
)

CREATE TABLE employee (
   id INTEGER NOT NULL,
   name VARCHAR,
   PRIMARY KEY (id)
)

CREATE TABLE link (
   department_id INTEGER NOT NULL,
   employee_id INTEGER NOT NULL,
   PRIMARY KEY (department_id, employee_id),
   FOREIGN KEY(department_id) REFERENCES department (id),
   FOREIGN KEY(employee_id) REFERENCES employee (id)
)

Bunu, aşağıdaki ekran görüntülerinde gösterildiği gibi SQLiteStudio kullanarak mycollege.db'yi açarak kontrol edebiliriz -

Daha sonra, aşağıda gösterildiği gibi Department sınıfının üç nesnesini ve Employee sınıfının üç nesnesini oluşturuyoruz -

d1 = Department(name = "Accounts")
d2 = Department(name = "Sales")
d3 = Department(name = "Marketing")

e1 = Employee(name = "John")
e2 = Employee(name = "Tony")
e3 = Employee(name = "Graham")

Her tablonun append () yöntemine sahip bir koleksiyon özelliği vardır. Employee nesneleri, Department nesnesinin Employees koleksiyonuna ekleyebiliriz. Benzer şekilde, Employee nesnelerinin departments collection özniteliğine Department nesneleri ekleyebiliriz.

e1.departments.append(d1)
e2.departments.append(d3)
d1.employees.append(e3)
d2.employees.append(e2)
d3.employees.append(e1)
e3.departments.append(d2)

Şimdi tek yapmamız gereken, bir oturum nesnesi oluşturmak, tüm nesneleri ona eklemek ve aşağıda gösterildiği gibi değişiklikleri uygulamak -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()
session.add(e1)
session.add(e2)
session.add(d1)
session.add(d2)
session.add(d3)
session.add(e3)
session.commit()

Python konsolunda aşağıdaki SQL ifadeleri yayınlanacaktır -

INSERT INTO department (name) VALUES (?) ('Accounts',)
INSERT INTO department (name) VALUES (?) ('Sales',)
INSERT INTO department (name) VALUES (?) ('Marketing',)
INSERT INTO employee (name) VALUES (?) ('John',)
INSERT INTO employee (name) VALUES (?) ('Graham',)
INSERT INTO employee (name) VALUES (?) ('Tony',)
INSERT INTO link (department_id, employee_id) VALUES (?, ?) ((1, 2), (3, 1), (2, 3))
INSERT INTO link (department_id, employee_id) VALUES (?, ?) ((1, 1), (2, 2), (3, 3))

Yukarıdaki işlemlerin etkisini kontrol etmek için SQLiteStudio kullanın ve departman, çalışan ve bağlantı tablolarındaki verileri görüntüleyin -

Verileri görüntülemek için aşağıdaki sorgu ifadesini çalıştırın -

from sqlalchemy.orm import sessionmaker
Session = sessionmaker(bind = engine)
session = Session()

for x in session.query( Department, Employee).filter(Link.department_id == Department.id, 
   Link.employee_id == Employee.id).order_by(Link.department_id).all():
   print ("Department: {} Name: {}".format(x.Department.name, x.Employee.name))

Örneğimizde doldurulan verilere göre, çıktı aşağıdaki gibi görüntülenecektir -

Department: Accounts Name: John
Department: Accounts Name: Graham
Department: Sales Name: Graham
Department: Sales Name: Tony
Department: Marketing Name: John
Department: Marketing Name: Tony

SQLAlchemy, çeşitli veritabanı türleri ile iletişim kurmak için lehçeler sistemini kullanır. Her veritabanının karşılık gelen bir DBAPI sarıcısı vardır. Tüm lehçeler, uygun bir DBAPI sürücüsünün kurulu olmasını gerektirir.

Aşağıdaki lehçeler SQLAlchemy API'sine dahil edilmiştir -

  • Firebird
  • Microsoft SQL Sunucusu
  • MySQL
  • Oracle
  • PostgreSQL
  • SQL
  • Sybase

Bir URL'ye dayalı bir Engine nesnesi, create_engine () işlevi tarafından üretilir. Bu URL'ler kullanıcı adı, şifre, ana bilgisayar adı ve veritabanı adını içerebilir. Ek yapılandırma için isteğe bağlı anahtar sözcük argümanları olabilir. Bazı durumlarda, bir dosya yolu kabul edilir ve bazılarında, "ana bilgisayar" ve "veritabanı" bölümlerinin yerini "veri kaynağı adı" alır. Bir veritabanı URL'sinin tipik biçimi aşağıdaki gibidir -

dialect+driver://username:password@host:port/database

PostgreSQL

PostgreSQL lehçesi kullanır psycopg2varsayılan DBAPI olarak. pg8000, aşağıda gösterildiği gibi saf Python yerine de kullanılabilir:

# default
engine = create_engine('postgresql://scott:tiger@localhost/mydatabase')

# psycopg2
engine = create_engine('postgresql+psycopg2://scott:tiger@localhost/mydatabase')

# pg8000
engine = create_engine('postgresql+pg8000://scott:tiger@localhost/mydatabase')

MySQL

MySQL lehçesi kullanır mysql-pythonvarsayılan DBAPI olarak. Aşağıdaki gibi MySQL-connector-python gibi birçok MySQL DBAPI mevcuttur -

# default
engine = create_engine('mysql://scott:tiger@localhost/foo')

# mysql-python
engine = create_engine('mysql+mysqldb://scott:tiger@localhost/foo')

# MySQL-connector-python
engine = create_engine('mysql+mysqlconnector://scott:tiger@localhost/foo')

Oracle

Oracle lehçesi kullanır cx_oracle aşağıdaki gibi varsayılan DBAPI olarak -

engine = create_engine('oracle://scott:[email protected]:1521/sidname')
engine = create_engine('oracle+cx_oracle://scott:tiger@tnsname')

Microsoft SQL Sunucusu

SQL Server lehçesi kullanır pyodbcvarsayılan DBAPI olarak. pymssql de mevcuttur.

# pyodbc
engine = create_engine('mssql+pyodbc://scott:tiger@mydsn')

# pymssql
engine = create_engine('mssql+pymssql://scott:tiger@hostname:port/dbname')

SQLite

SQLite, Python yerleşik modülünü kullanarak dosya tabanlı veritabanlarına bağlanır sqlite3varsayılan olarak. SQLite yerel dosyalara bağlandığından, URL biçimi biraz farklıdır. URL'nin "dosya" kısmı, veritabanının dosya adıdır. Göreli bir dosya yolu için bu, aşağıda gösterildiği gibi üç eğik çizgi gerektirir -

engine = create_engine('sqlite:///foo.db')

Ve mutlak bir dosya yolu için, üç eğik çizgiyi aşağıda verilen mutlak yol izler -

engine = create_engine('sqlite:///C:\\path\\to\\foo.db')

Bir SQLite: memory: veritabanı kullanmak için, aşağıda verildiği gibi boş bir URL belirtin -

engine = create_engine('sqlite://')

Sonuç

Bu öğreticinin ilk bölümünde, SQL ifadelerini yürütmek için İfade Dilinin nasıl kullanılacağını öğrendik. İfade dili SQL yapılarını Python koduna gömer. İkinci bölümde, SQLAlchemy'nin nesne ilişkisi haritalama yeteneğini tartıştık. ORM API, SQL tablolarını Python sınıflarıyla eşler.