데이터 연결 수정하기
데이터 연결 수정하기 (Update Data Connections)
이번 장에서는 테이블과 테이블 사이의 연결을 바꾸는 방법을 배워요. 이미 만들어진 히어로에게 다른 팀을 배정하는 식으로요.
출처: 공식문서
현재 데이터 상태
지금 우리는 team 테이블과 hero 테이블이 이렇게 연결되어 있어요.
team 테이블:
| id | name | headquarters |
|---|---|---|
| 1 | Preventers | Sharp Tower |
| 2 | Z-Force | Sister Margaret's Bar |
hero 테이블:
| id | name | secret_name | age | team_id |
|---|---|---|---|---|
| 1 | Deadpond | Dive Wilson | null | 2 |
| 2 | Rusty-Man | Tommy Sharp | 48 | 1 |
| 3 | Spider-Boy | Pedro Parqueador | null | null |
일부 히어로는 팀에 속해 있죠. 이제 이 행들 사이의 연결을 어떻게 수정하는지 볼 거예요.
이전 장에서 히어로를 만들 때 썼던 코드를 이어서 사용할게요.
from sqlmodel import Field, Session, SQLModel, create_engine
class Team(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
headquarters: str
class Hero(SQLModel, table=True):
id: int | None = Field(default=None, primary_key=True)
name: str = Field(index=True)
secret_name: str
age: int | None = Field(default=None, index=True)
team_id: int | None = Field(default=None, foreign_key="team.id")
sqlite_file_name = "database.db"
sqlite_url = f"sqlite:///{sqlite_file_name}"
engine = create_engine(sqlite_url, echo=True)
def create_db_and_tables():
SQLModel.metadata.create_all(engine)
def create_heroes():
with Session(engine) as session:
team_preventers = Team(name="Preventers", headquarters="Sharp Tower")
team_z_force = Team(name="Z-Force", headquarters="Sister Margaret's Bar")
session.add(team_preventers)
session.add(team_z_force)
session.commit()
hero_deadpond = Hero(
name="Deadpond", secret_name="Dive Wilson", team_id=team_z_force.id
)
hero_rusty_man = Hero(
name="Rusty-Man",
secret_name="Tommy Sharp",
age=48,
team_id=team_preventers.id,
)
hero_spider_boy = Hero(name="Spider-Boy", secret_name="Pedro Parqueador")
session.add(hero_deadpond)
session.add(hero_rusty_man)
session.add(hero_spider_boy)
session.commit()
session.refresh(hero_deadpond)
session.refresh(hero_rusty_man)
session.refresh(hero_spider_boy)
print("Created hero:", hero_deadpond)
print("Created hero:", hero_rusty_man)
print("Created hero:", hero_spider_boy)
def main():
create_db_and_tables()
create_heroes()
if __name__ == "__main__":
main()
히어로에게 팀 배정하기
스토리상으로, Tommy Sharp가 자신의 "부자 삼촌" 매력을 이용해 Spider-Boy를 Preventers 팀에 끌어들이기로 했어요. 이제 우리의 Spider-Boy 히어로 객체를 Preventers 팀에 연결하기 위해 업데이트해야 해요.
하는 방법은 다른 필드를 업데이트할 때와 똑같아요.
team_id 필드 속성에 값을 할당하면 돼요. 그다음 히어로를 add() 하고, commit() 하면 됩니다.
# Code above omitted 👆
def create_heroes():
with Session(engine) as session:
# Code here omitted 👈
hero_spider_boy.team_id = team_preventers.id
session.add(hero_spider_boy)
session.commit()
session.refresh(hero_spider_boy)
print("Updated hero:", hero_spider_boy)
# Code below omitted 👇
이어서 refresh() 로 최신 데이터를 가져와서 출력해 보죠.
명령줄에서 실행하면 이렇게 출력됩니다.
$ uv run python app.py
// Previous output omitted 😉
// Update the hero
INFO Engine UPDATE hero SET team_id=? WHERE hero.id = ?
INFO Engine [generated in 0.00014s] (1, 3)
// Commit the session saving the changes
INFO Engine COMMIT
// Automatically start a new transaction
INFO Engine BEGIN (implicit)
// Refresh the hero data
INFO Engine SELECT hero.id, hero.name, hero.secret_name, hero.age, hero.team_id
FROM hero
WHERE hero.id = ?
INFO Engine [cached since 0.08837s ago] (3,)
// Print the updated hero
Updated hero: id=3 secret_name='Pedro Parqueador' team_id=1 name='Spider-Boy' age=None
이제 Spider-Boy는 team_id=1을 갖게 됐어요. 이게 바로 Preventers의 ID예요. 🎉
연결을 수정하는 건 "필드 하나에 값을 다시 할당하면 끝"입니다. 데이터베이스가 알아서 그 행을 업데이트해요.
다음 장에서는 연결을 어떻게 끊어내는지 볼게요. 💥