Поврзување преку табела за врска во Python
Нека сега корисникот бил во различни градови. Во овој случај, табелата со корисници можеби би имала следниот изглед:
| 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-а: првиот join ќе ја приклучи табелата за врска кон корисниците, а вториот 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
Резултат од барањето
Резултатот од нашето барање во Python ќе содржи име на секој корисник онолку пати, со колку градови е поврзан:
{'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>