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 |
Сўровлар
Келтинглар, фойдаланувчиларни уларнинг шаҳарлари билан бирга олиб чиқадиган сўров қилайлик. Бунинг учун bизга иккита джоин керак бўлади: биринчи джоин фойдаланувчиларга алоқа таблицасини қўшади, ва иккинчи джоин алоқалар орқали шаҳарларни қўшади:
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
Сўров натижаси
Бизнинг сўровимизнинг Pythondagi натижаси ҳар бир фойдаланувчи исмини шунча марта ўз ичига олади, у нечта шаҳар билан богланган бўлса:
{'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>