Lidhja përmes tabelës së lidhjes në Python
Le të supozojmë tani që përdoruesi ka qenë në qytete të ndryshme. Në këtë rast, tabela me përdoruesit mund të ketë pamjen e mëposhtme:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Është e qartë se ruajtja e të dhënave në këtë mënyrë është e gabuar - qytetet duhet të nxirren në një tabelë të veçantë. Ja ku është ajo:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Sidoqoftë, ne duhet të bëjmë që çdo përdorues të mund të referohet në disa qytete. Duke përdorur dy tabela kjo është e pamundur.
Do të na duhet të prezantojmë të ashtuquajturën tabelë lidhëse, e cila do të lidhë përdoruesin me qytetet e tij.
Në çdo regjistrim të kësaj tabele do të ruhet lidhja midis një përdoruesi dhe një qyteti. Duke patur parasysh këtë, për një përdorues në këtë tabelë do të ketë sa regjistrime, në sa qytete ka qenë ai.
Ja tabela jonë lidhëse:
| 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 |
Tabela me përdoruesit do të ruajë vetëm emrat e përdoruesve, pa lidhje:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Kërkesat
Le të bëjmë një kërkesë, me ndihmën e së cilës do të nxjerrim përdoruesit së bashku me qytetet e tyre. Për këtë do të na duhen dy kryqëzime (join): kryqëzimi i parë do të bashkojë me përdoruesit tabelën lidhëse, dhe kryqëzimi i dytë përmes lidhjeve do të bashkojë qytetet:
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
Rezultati i kërkesës
Rezultati i kërkesës sonë në Python do të përmbajë emrin e çdo përdoruesi aq herë, me sa qytete është i lidhur ai:
{'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}
Më praktik do të ishte të konvertohej një fjalor i tillë dhe ta kthenim atë në formën e mëposhtme:
{
'user1': ['city1', 'city2', 'city3'],
'user2': ['city1', 'city2'],
'user3': ['city2', 'city3'],
'user4': ['city1'],
'user5': []
}
Le të shkruajmë kodin që kryen një konvertim të tillë.
Le të bëjmë një fjalor bosh user_cities_dct,
në të cilin gradualisht do të fusim të dhëna
për përdoruesit dhe qytetet, në të cilët kanë qenë.
Në ciklin for deklarojmë dy variabla
user_name dhe city_name, në
të cilat do të ruhen emri i përdoruesit dhe emri
i qytetit. Më pas shkruajmë një kusht - nëse
përdoruesi nuk gjendet në user_cities_dct, atëherë ai
do të shtohet në këtë fjalor si çelës.
Gjithashtu, le të specifikojmë kushtin, që nëse city_name
nuk është None, atëherë ai do të shtohet si vlerë
e çelësit:
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)
Detyra praktike
Le të supozojmë që një produkt mund t'i përkasë disa kategori. Përshkruani strukturën e ruajtjes.
Shkruani një kërkesë, e cila do të nxjerrë produktet së bashku me kategoritë e tyre.
Shfaqni të dhënat e marra në formën e një liste
ul ashtu që në çdo li
në fillim të qëndrojë emri i produktit, dhe pas
pikës dy-pika të listohen, të ndara me presje,
kategoritë e këtij produkti. Përafërsisht kështu:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>