Повезивање преко табеле везе у Пајтону
Претпоставимо сада да је корисник био у различитим градовима. У овом случају табела са корисницима би могла да има следећи изглед:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Јасно је да није исправно тако чувати податке - градове треба издвојити у посебну табелу. Ево ње:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Међутим, потребно је да урадимо тако да сваки корисник може да упућује на више градова. Са две табеле то није могуће урадити.
Биће нам потребно да увеђемо такозвану табелу везе, која ће повезивати корисника са његовим градовима.
У сваком запису ове табеле ће се чувати веза између корисника и једног града. При томе за једног корисника у овој табели ће бити толико записа, у колико градова је он био.
Ево наше табеле везе:
| 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 |
Табела са корисницима ће чувати само имена корисника, без веза:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Упити
Хајде да направимо упит, помоћу ког извучемо кориснике заједно са њиховим градовима. За ово ће нам требати да урадимо два споја (join): први спој ће прикључити корисницима табелу везе, а други спој преко веза ће прикључити градове:
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
Резултат упита
Резултат нашег упита у Пајтону ће садржати име сваког корисника онолико пута, са колико градова је повезан:
{'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}
Било би згодније да се такав речник преконвертује и претвори у следећи:
{
'user1': ['city1', 'city2', 'city3'],
'user2': ['city1', 'city2'],
'user3': ['city2', 'city3'],
'user4': ['city1'],
'user5': []
}
Написаћемо код који врши такву конверзију.
Направимо празан речник user_cities_dct,
у који ћемо постепено уносити податке
о корисницима и градовима, у којима су били.
У петљи for декларишемо две променљиве
user_name и city_name, у
којима ће се чувати име корисника и назив
града. Затим прописујемо услов - ако
корисника нема у user_cities_dct, онда ће се он
додати у овај речник као кључ.
Такође наводимо услов да ако city_name
није None, да ће се додати као вредност
кључа:
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)
Практични задаци
Претпоставимо да производ може припадати неколико категорија. Описати структуру складиштења.
Напишите упит који ће извући производе заједно са њиховим категоријама.
Прикажите добијене податке у виду списка
ul тако да у свакој li
на почетку стоји име производа, а после
двотачке преко зареза набројане
категорије тог производа. Отприлике овако:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>