Python'da Bağlantı Tablosu ile İlişkilendirme
Şimdi kullanıcının farklı şehirlerde bulunduğunu varsayalım. Bu durumda kullanıcılar tablosu şu şekilde olabilir:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Verileri bu şekilde saklamanın yanlış olduğu açıktır - şehirler ayrı bir tabloya taşınmalıdır. İşte o tablo:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Ancak, her kullanıcının birden fazla şehre referans verebilmesini sağlamamız gerekiyor. Bunu iki tablo ile yapmak imkansızdır.
Kullanıcıyı şehirleriyle bağlayan, sözde bağlantı tablosu olarak adlandırılan bir tabloya ihtiyacımız olacak.
Bu tablodaki her kayıt, bir kullanıcı ile bir şehir arasındaki bağlantıyı saklayacaktır. Bu durumda, bir kullanıcı için bu tabloda, bulunduğu şehir sayısı kadar kayıt olacaktır.
İşte bağlantı tablomuz:
| id | user_id | city_id |
|---|---|---|
| 1 | 1 | 1 |
| 2 | 1 | 2 |
| 3 | 1 | 3 |
| 4 | 2 | 1 |
| 5 | 2 | 2 |
| 6 | 3 | 2 |
| 7 | 3 | 3 |
| 8 | 4 | 1 |
Kullanıcılar tablosu sadece kullanıcı adlarını, bağlantılar olmadan saklayacaktır:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Sorgular
Kullanıcıları şehirleriyle birlikte getiren bir sorgu yapalım. Bunun için iki join işlemine ihtiyacımız olacak: ilk join, kullanıcılara bağlantı tablosunu ekleyecek, ikinci join ise bağlantılar üzerinden şehirleri ekleyecek:
SELECT
users.name as user_name, cities.name as city_name
FROM
users
LEFT JOIN users_cities ON users_cities.user_id=users.id
LEFT JOIN cities ON users_cities.city_id=cities.id
Sorgu Sonucu
Python'daki sorgumuzun sonucu, her kullanıcının adını, bağlantılı olduğu şehir sayısı kadar tekrarlayacaktır:
{'user_name': 'user1', 'city_name': 'city1'}
{'user_name': 'user1', 'city_name': 'city2'}
{'user_name': 'user1', 'city_name': 'city3'}
{'user_name': 'user2', 'city_name': 'city1'}
{'user_name': 'user2', 'city_name': 'city2'}
{'user_name': 'user3', 'city_name': 'city2'}
{'user_name': 'user3', 'city_name': 'city3'}
{'user_name': 'user4', 'city_name': 'city1'}
{'user_name': 'user5', 'city_name': None}
Böyle bir sözlüğü dönüştürmek ve onu aşağıdaki hale getirmek daha uygun olurdu:
{
'user1': ['city1', 'city2', 'city3'],
'user2': ['city1', 'city2'],
'user3': ['city2', 'city3'],
'user4': ['city1'],
'user5': []
}
Böyle bir dönüşümü gerçekleştiren kodu yazalım.
Kullanıcılar ve bulundukları şehirler hakkında verileri
aşamalı olarak gireceğimiz boş bir user_cities_dct sözlüğü yapalım.
for döngüsü içinde, kullanıcı adını ve şehir adını
tutan iki değişken tanımlıyoruz: user_name ve city_name.
Ardından bir koşul yazıyoruz - eğer
kullanıcı user_cities_dct içinde yoksa, bu sözlüğe
bir anahtar olarak eklenecektir.
Ayrıca, eğer city_name
None değilse, anahtarın değeri olarak ekleneceğini belirtiyoruz:
result = cursor.fetchall()
user_cities_dct = {}
for row in result:
user_name = row['user_name']
city_name = row['city_name']
if user_name not in user_cities_dct:
user_cities_dct[user_name] = []
if city_name is not None:
user_cities_dct[user_name].append(city_name)
print(user_cities_dct)
Pratik Görevler
Bir ürünün birden fazla kategoriye ait olabileceğini varsayalım. Saklama yapısını açıklayın.
Ürünleri kategorileriyle birlikte getiren bir sorgu yazın.
Elde edilen verileri, her li içinde
önce ürün adının yer aldığı, ardından iki nokta üst üste işaretinden sonra
virgülle ayrılmış olarak bu ürünün kategorilerinin listelendiği
bir ul listesi şeklinde görüntüleyin. Örneğin şu şekilde:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>