Koppeling deur 'n koppelingstabel in Python
Gestel 'n gebruiker was nou in verskillende stede. In hierdie geval kan die tabel met gebruikers die volgende voorkoms hê:
| id | name | city |
|---|---|---|
| 1 | user1 | city1, city2, city3 |
| 2 | user2 | city1, city2 |
| 3 | user3 | city2, city3 |
| 4 | user4 | city1 |
Dit is duidelik dat dit verkeerd is om data so te stoor - die stede moet in 'n aparte tabel geplaas word. Hier is dit:
| id | name |
|---|---|
| 1 | city1 |
| 2 | city2 |
| 3 | city3 |
Ons moet egter maak dat elke gebruiker na verskeie stede kan verwys. Met twee tabelle is dit onmoontlik.
Ons sal die sogenaamde koppelingstabel moet invoer, wat die gebruiker aan sy stede sal koppel.
In elke inskrywing van hierdie tabel sal die koppeling tussen 'n gebruiker en een stad gestoor word. By die geleentheid vir een gebruiker in hierdie tabel sal daar soveel inskrywings wees as in hoeveel stede hy was.
Hier is ons koppelingstabel:
| 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 |
Die tabel met gebruikers sal slegs die name van die gebruikers stoor, sonder koppelings:
| id | name |
|---|---|
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
| 4 | user4 |
| 5 | user5 |
Navrae
Kom ons maak 'n navraag waarmee ons die gebruikers saam met hul stede sal uithaal. Vir dit sal ons twee joins moet doen: die eerste join sal die koppelingstabel by die gebruikers voeg, en die tweede join sal die stede volgens die koppelings byvoeg:
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
Resultaat van die navraag
Die resultaat van ons navraag in Python sal die naam van elke gebruiker bevat soveel keer met hoeveel stede hy gekoppel is:
{'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}
Dit sou geriefliker wees om so 'n woordeboek te omskep en dit in die volgende te verander:
{
'user1': ['city1', 'city2', 'city3'],
'user2': ['city1', 'city2'],
'user3': ['city2', 'city3'],
'user4': ['city1'],
'user5': []
}
Kom ons skryf die kode wat so 'n omskakeling doen.
Ons maak 'n leë woordeboek user_cities_dct,
waarin ons geleidelik data oor
gebruikers en die stede sal invoer waar hulle was.
In die lus for verklaar ons twee veranderlikes
user_name en city_name, in
wat die naam van die gebruiker en die naam
van die stad gestoor sal word. Dan skryf ons die voorwaarde - as
die gebruiker nie in user_cities_dct is nie, dan sal hy
by hierdie woordeboek as 'n sleutel gevoeg word.
Ons sal ook die voorwaarde spesifiseer dat as city_name
nie None is nie, dan sal dit as waarde
van die sleutel bygevoeg word:
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)
Praktiese take
Gestel 'n produk kan aan verskeie kategorieë behoort. Skryf die stoorstruktuur uit.
Skryf 'n navraag wat die produkte saam met hul kategorieë sal uithaal.
Vertoon die verkreë data in die vorm van 'n lys
ul sodat in elke li
eers die naam van die produk staan, en na
die dubbelpunt word die kategorieë van hierdie produk deur kommas gelys. Ongeveer so:
<ul>
<li>product1: category1, category2, category3</li>
<li>product2: category1, category3</li>
<li>product3: category1</li>
</ul>