๐ (๐) ๐ฝ¶
FastAPI ๐ซ ๐ ๐ โ๏ธ ๐ (๐) ๐ฝ.
โ๏ธ ๐ ๐ช โ๏ธ ๐ ๐ ๐ฝ ๐ ๐ ๐.
๐ฅ ๐ฅ ๐ ๐ ๐ผ โ๏ธ ๐ธ๐ฒ.
๐ ๐ช ๐ช ๐ ๏ธ โซ๏ธ ๐ ๐ฝ ๐โ๐ฆบ ๐ธ๐ฒ, ๐:
- โณ
- โณ
- ๐
- ๐ธ
- ๐คธโโ ๐ ๐ฝ, โ๏ธ.
๐ ๐ผ, ๐ฅ ๐ โ๏ธ ๐, โฉ๏ธ โซ๏ธ โ๏ธ ๐ ๐ & ๐ โ๏ธ ๐ ๏ธ ๐โ๐ฆบ. , ๐ ๐ช ๐ ๐ ๐ผ & ๐ โซ๏ธ.
โช, ๐ ๐ญ ๐ธ, ๐ ๐ช ๐ โ๏ธ ๐ฝ ๐ฝ ๐ โณ.
Tip
๐ค ๐ ๐ ๐ โฎ๏ธ FastAPI & โณ, ๐ โ๏ธ ๐ โ, ๐ ๐ธ & ๐ ๐งฐ: https://github.com/tiangolo/full-stack-fastapi-postgresql
Note
๐ ๐ ๐ ๐ ๐ฉ SQLAlchemy ๐ ๐ ๐ โ๏ธ โฎ๏ธ ๐ ๐ ๏ธ.
FastAPI ๐ฏ ๐ ๐คช ๐ง.
๐¶
FastAPI ๐ท โฎ๏ธ ๐ ๐ฝ & ๐ ๐ ๐ ๐ฌ ๐ฝ.
โ โ โ๏ธ "๐": "๐-๐ ๐บ" ๐.
๐ โ๏ธ ๐งฐ ๐ ("๐บ") ๐ ๐ ๐ & ๐ฝ ๐ ("๐").
โฎ๏ธ ๐, ๐ ๐ โ ๐ ๐ ๐จ ๐ ๐ ๐ฝ, ๐ ๐ข ๐ ๐จ ๐, โฎ๏ธ ๐ & ๐.
๐ผ ๐ Pet ๐ช ๐จ ๐ ๐ pets.
& ๐ ๐ ๐ ๐ ๐ ๐จ โญ ๐ฝ.
๐ผ ๐ orion_cat (๐ Pet) ๐ช โ๏ธ ๐ข orion_cat.type, ๐ type. & ๐ฒ ๐ ๐ข ๐ช, โ
"cat".
๐ซ ๐ โ๏ธ ๐งฐ โ ๐ โ๏ธ ๐ ๐ ๐ โ๏ธ ๐จโ๐ผ.
๐ ๐, ๐ ๐ช โ๏ธ ๐ข orion_cat.owner & ๐จโ๐ผ ๐ ๐ ๐ฝ ๐ ๐ถ ๐จโ๐ผ, โ โช๏ธโก๏ธ ๐ ๐จโ๐ผ.
, orion_cat.owner.name ๐ช ๐ (โช๏ธโก๏ธ name ๐ owners ๐) ๐ ๐ถ ๐จโ๐ผ.
โซ๏ธ ๐ช โ๏ธ ๐ฒ ๐ "Arquilian".
& ๐ ๐ ๐ ๐ท ๐ค โน โช๏ธโก๏ธ ๐ ๐ ๐จโ๐ผ ๐โ ๐ ๐ ๐ โซ๏ธ โช๏ธโก๏ธ ๐ ๐ถ ๐.
โ ๐ ๐ผ: โณ-๐ (๐ โณ ๐ ๏ธ), ๐ธ๐ฒ ๐ (๐ ๐ธ๐ฒ, ๐ฌ ๐ ๏ธ) & ๐ (๐ฌ ๐ ๏ธ), ๐ช ๐.
๐ฅ ๐ฅ ๐ ๐ โ ๐ท โฎ๏ธ ๐ธ๐ฒ ๐.
๐ ๐ ๐ ๐ช โ๏ธ ๐ ๐ ๐.
Tip
๐ค ๐ ๐ โ๏ธ ๐ ๐ฅ ๐ฉบ.
๐ ๐¶
๐ซ ๐ผ, โก๏ธ ๐ฌ ๐ โ๏ธ ๐ ๐ my_super_project ๐ ๐ ๐ง-๐ ๐ค sql_app โฎ๏ธ ๐ ๐ ๐:
.
โโโ sql_app
โโโ __init__.py
โโโ crud.py
โโโ database.py
โโโ main.py
โโโ models.py
โโโ schemas.py
๐ __init__.py ๐ ๐, โ๏ธ โซ๏ธ ๐ฌ ๐ ๐ sql_app โฎ๏ธ ๐ ๐ฎ ๐น (๐ ๐) ๐ฆ.
๐ โก๏ธ ๐ โซ๏ธโ ๐ ๐/๐น ๐จ.
โ SQLAlchemy¶
๐ฅ ๐ ๐ช โ SQLAlchemy:
$ pip install sqlalchemy
---> 100%
โ ๐ธ๐ฒ ๐¶
โก๏ธ ๐ ๐ sql_app/database.py.
๐ ๐ธ๐ฒ ๐¶
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
โ ๐ฝ ๐ ๐ธ๐ฒ¶
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
๐ ๐ผ, ๐ฅ "๐" ๐ ๐ฝ (๐ ๐ โฎ๏ธ ๐ ๐ฝ).
๐ ๐ ๐ ๐ ๐ ๐ sql_app.db.
๐ โซ๏ธโ ๐ ๐ ./sql_app.db.
๐ฅ ๐ โ๏ธ โณ ๐ฝ โฉ๏ธ, ๐ ๐ โ๏ธ โ โธ:
SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
...& ๐ ๏ธ โซ๏ธ โฎ๏ธ ๐ ๐ฝ ๐ & ๐ (๐ โณ, โณ โ๏ธ ๐ ๐).
Tip
๐ ๐ โธ ๐ ๐ ๐ โ๏ธ ๐ ๐ฅ ๐ ๐ โ๏ธ ๐ ๐ฝ.
โ ๐ธ๐ฒ engine¶
๐ฅ ๐ โ ๐ธ๐ฒ "๐".
๐ฅ ๐ โช โ๏ธ ๐ engine ๐ ๐ฅ.
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
๐¶
โ:
connect_args={"check_same_thread": False}
...๐ช ๐ด SQLite. โซ๏ธ ๐ซ ๐ช ๐ ๐ฝ.
๐ก โน
๐ข ๐ ๐ ๐ด โ 1๏ธโฃ ๐งต ๐ โฎ๏ธ โซ๏ธ, ๐ค ๐ ๐ ๐งต ๐ ๐ต ๐ฌ ๐จ.
๐ โ ๐ซ ๐ค ๐ ๐ ๐ ๐ (๐ ๐จ).
โ๏ธ FastAPI, โ๏ธ ๐ ๐ข (def) ๐
๐ 1๏ธโฃ ๐งต ๐ช ๐ โฎ๏ธ ๐ฝ ๐ ๐จ, ๐ฅ ๐ช โ ๐ ๐ญ ๐ โซ๏ธ ๐ โ ๐ โฎ๏ธ connect_args={"check_same_thread": False}.
, ๐ฅ ๐ โ ๐ญ ๐ ๐จ ๐ค ๐ฎ ๐ ๐ฝ ๐ ๐ ๐, ๐ค ๐ โโ ๐ช ๐ ๐ข ๐ ๏ธ.
โ SessionLocal ๐¶
๐ ๐ SessionLocal ๐ ๐ ๐ฝ ๐. ๐ โซ๏ธ ๐ซ ๐ฝ ๐.
โ๏ธ ๐ ๐ฅ โ ๐ SessionLocal ๐, ๐ ๐ ๐ โ ๐ฝ ๐.
๐ฅ ๐ โซ๏ธ SessionLocal ๐ฌ โซ๏ธ โช๏ธโก๏ธ Session ๐ฅ ๐ญ โช๏ธโก๏ธ ๐ธ๐ฒ.
๐ฅ ๐ โ๏ธ Session (1๏ธโฃ ๐ โช๏ธโก๏ธ ๐ธ๐ฒ) โช.
โ SessionLocal ๐, โ๏ธ ๐ข sessionmaker:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
โ Base ๐¶
๐ ๐ฅ ๐ โ๏ธ ๐ข declarative_base() ๐ ๐จ ๐.
โช ๐ฅ ๐ ๐ โช๏ธโก๏ธ ๐ ๐ โ ๐ ๐ฝ ๐ท โ๏ธ ๐ (๐ ๐ท):
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
โ ๐ฝ ๐ท¶
โก๏ธ ๐ ๐ ๐ sql_app/models.py.
โ ๐ธ๐ฒ ๐ท โช๏ธโก๏ธ Base ๐¶
๐ฅ ๐ โ๏ธ ๐ Base ๐ ๐ฅ โ โญ โ ๐ธ๐ฒ ๐ท.
Tip
๐ธ๐ฒ โ๏ธ โ "๐ท" ๐ ๐ ๐ & ๐ ๐ ๐ โฎ๏ธ ๐ฝ.
โ๏ธ Pydantic โ๏ธ โ "๐ท" ๐ ๐ณ ๐, ๐ฝ ๐ฌ, ๐ ๏ธ, & ๐งพ ๐ & ๐.
๐ Base โช๏ธโก๏ธ database (๐ database.py โช๏ธโก๏ธ ๐).
โ ๐ ๐ ๐ โช๏ธโก๏ธ โซ๏ธ.
๐ซ ๐ ๐ธ๐ฒ ๐ท.
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
items = relationship("Item", back_populates="owner")
class Item(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
owner_id = Column(Integer, ForeignKey("users.id"))
owner = relationship("User", back_populates="items")
__tablename__ ๐ข ๐ฌ ๐ธ๐ฒ ๐ ๐ โ๏ธ ๐ฝ ๐ ๐ซ ๐ท.
โ ๐ท ๐ข/๐¶
๐ โ ๐ ๐ท (๐) ๐ข.
๐ ๐ซ ๐ข ๐จ ๐ ๐ฎ ๐ ๐ฝ ๐.
๐ฅ โ๏ธ Column โช๏ธโก๏ธ ๐ธ๐ฒ ๐ข ๐ฒ.
& ๐ฅ ๐ถโโ๏ธ ๐ธ๐ฒ ๐ "๐", Integer, String, & Boolean, ๐ ๐ฌ ๐ ๐ฝ, โ.
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
items = relationship("Item", back_populates="owner")
class Item(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
owner_id = Column(Integer, ForeignKey("users.id"))
owner = relationship("User", back_populates="items")
โ ๐¶
๐ โ ๐.
๐, ๐ฅ โ๏ธ relationship ๐ ๐ธ๐ฒ ๐.
๐ ๐ โถ๏ธ๏ธ, ๐ โ๏ธ ๐, "๐ฑ" ๐ข ๐ ๐ ๐ ๐ฒ โช๏ธโก๏ธ ๐ ๐ ๐ ๐ 1๏ธโฃ.
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
items = relationship("Item", back_populates="owner")
class Item(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
owner_id = Column(Integer, ForeignKey("users.id"))
owner = relationship("User", back_populates="items")
๐โ ๐ ๐ข items User, my_user.items, โซ๏ธ ๐ โ๏ธ ๐ Item ๐ธ๐ฒ ๐ท (โช๏ธโก๏ธ items ๐) ๐ โ๏ธ ๐ฑ ๐ โ ๐ โบ users ๐.
๐โ ๐ ๐ my_user.items, ๐ธ๐ฒ ๐ ๐ค ๐ถ & โ ๐ฌ โช๏ธโก๏ธ ๐ฝ items ๐ & ๐ ๐ซ ๐ฅ.
& ๐โ ๐ ๐ข owner Item, โซ๏ธ ๐ ๐ User ๐ธ๐ฒ ๐ท โช๏ธโก๏ธ users ๐. โซ๏ธ ๐ โ๏ธ owner_id ๐ข/๐ โฎ๏ธ ๐ฎ ๐ฑ ๐ ๐ญ โ โบ ๐ค โช๏ธโก๏ธ users ๐.
โ Pydantic ๐ท¶
๐ โก๏ธ โ
๐ sql_app/schemas.py.
Tip
โ ๐จ ๐ ๐ธ๐ฒ ๐ท & Pydantic ๐ท, ๐ฅ ๐ โ๏ธ ๐ models.py โฎ๏ธ ๐ธ๐ฒ ๐ท, & ๐ schemas.py โฎ๏ธ Pydantic ๐ท.
๐ซ Pydantic ๐ท ๐ฌ ๐ โ๏ธ ๐ "๐" (โ ๐ ๐ ).
๐ ๐ โน ๐ฅ โ ๐จ โช โ๏ธ ๐ฏโโ๏ธ.
โ โถ๏ธ Pydantic ๐ท / ๐¶
โ ItemBase & UserBase Pydantic ๐ท (โ๏ธ โก๏ธ ๐ฌ "๐") โ๏ธ โ ๐ข โช ๐ โ๏ธ ๐ ๐.
& โ ItemCreate & UserCreate ๐ ๐ โช๏ธโก๏ธ ๐ซ (๐ซ ๐ โ๏ธ ๐ ๐ข), โ ๐ ๐ ๐ (๐ข) ๐ช ๐.
, ๐ฉโ๐ป ๐ โ๏ธ password ๐โ ๐ โซ๏ธ.
โ๏ธ ๐โโ, password ๐ ๐ซ ๐ Pydantic ๐ท, ๐ผ, โซ๏ธ ๐ ๐ซ ๐จ โช๏ธโก๏ธ ๐ ๏ธ ๐โ ๐ ๐ฉโ๐ป.
from typing import List, Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: List[Item] = []
class Config:
orm_mode = True
from typing import Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: str | None = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
๐ธ๐ฒ ๐ & Pydantic ๐¶
๐ ๐ ๐ธ๐ฒ ๐ท ๐ฌ ๐ข โ๏ธ =, & ๐ถโโ๏ธ ๐ ๐ข Column, ๐:
name = Column(String)
โช Pydantic ๐ท ๐ฃ ๐ โ๏ธ :, ๐ ๐ โ โ/๐ ๐:
name: str
โ๏ธ โซ๏ธ ๐คฏ, ๐ ๐ซ ๐ค ๐ ๐โ โ๏ธ = & : โฎ๏ธ ๐ซ.
โ Pydantic ๐ท / ๐ ๐ / ๐จ¶
๐ โ Pydantic ๐ท (๐) ๐ ๐ โ๏ธ ๐โ ๐ ๐ฝ, ๐โ ๐ฌ โซ๏ธ โช๏ธโก๏ธ ๐ ๏ธ.
๐ผ, โญ ๐ ๐ฌ, ๐ฅ ๐ซ ๐ญ โซ๏ธโ ๐ ๐ ๐ ๏ธ โซ๏ธ, โ๏ธ ๐โ ๐ โซ๏ธ (๐โ ๐ฌ โซ๏ธ โช๏ธโก๏ธ ๐ ๏ธ) ๐ฅ ๐ โช ๐ญ ๐ฎ ๐.
๐ ๐, ๐โ ๐ ๐ฉโ๐ป, ๐ฅ ๐ช ๐ ๐ฃ ๐ items ๐ ๐ ๐ฌ ๐ ๐ญ ๐ ๐ฉโ๐ป.
๐ซ ๐ด ๐ ๐ ๐ฌ, โ๏ธ ๐ ๐ฝ ๐ ๐ฅ ๐ฌ Pydantic ๐ท ๐ ๐ฌ: Item.
from typing import List, Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: List[Item] = []
class Config:
orm_mode = True
from typing import Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: str | None = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
Tip
๐ ๐ User, Pydantic ๐ท ๐ ๐ โ๏ธ ๐โ ๐ ๐ฉโ๐ป (๐ฌ โซ๏ธ โช๏ธโก๏ธ ๐ ๏ธ) ๐ซ ๐ password.
โ๏ธ Pydantic orm_mode¶
๐, Pydantic ๐ท ๐, Item & User, ๐ฎ ๐ Config ๐.
๐ Config ๐ โ๏ธ ๐ ๐ณ Pydantic.
Config ๐, โ ๐ข orm_mode = True.
from typing import List, Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: List[Item] = []
class Config:
orm_mode = True
from typing import Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: str | None = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
Tip
๐ โซ๏ธ โ ๐ฒ โฎ๏ธ =, ๐:
orm_mode = True
โซ๏ธ ๐ซ โ๏ธ : ๐ ๐ โญ.
๐ โ ๐ ๐ฒ, ๐ซ ๐ฃ ๐.
Pydantic orm_mode ๐ ๐ฌ Pydantic ๐ท โ ๐ฝ ๐ฅ โซ๏ธ ๐ซ dict, โ๏ธ ๐ ๐ท (โ๏ธ ๐ ๐ โ ๐ โฎ๏ธ ๐ข).
๐ ๐, โฉ๏ธ ๐ด ๐ ๐ค id ๐ฒ โช๏ธโก๏ธ dict,:
id = data["id"]
โซ๏ธ ๐ ๐ ๐ค โซ๏ธ โช๏ธโก๏ธ ๐ข,:
id = data.id
& โฎ๏ธ ๐, Pydantic ๐ท ๐ โฎ๏ธ ๐, & ๐ ๐ช ๐ฃ โซ๏ธ response_model โ ๐ โก ๐ ๏ธ.
๐ ๐ ๐ช ๐จ ๐ฝ ๐ท & โซ๏ธ ๐ โ ๐ฝ โช๏ธโก๏ธ โซ๏ธ.
๐ก โน ๐ ๐ ๐ณ¶
๐ธ๐ฒ & ๐ ๐ ๐ข "๐ ๐".
๐ โ, ๐ผ, ๐ ๐ซ ๐ซ โ ๐ฝ ๐ โช๏ธโก๏ธ ๐ฝ ๐ฅ ๐ ๐ ๐ ๐ข ๐ ๐ ๐ ๐ ๐ฝ.
๐ผ, ๐ ๐ข items:
current_user.items
๐ โ ๐ธ๐ฒ ๐ถ items ๐ & ๐ค ๐ฌ ๐ ๐ฉโ๐ป, โ๏ธ ๐ซ โญ.
๐ต orm_mode, ๐ฅ ๐ ๐จ ๐ธ๐ฒ ๐ท โช๏ธโก๏ธ ๐ โก ๐ ๏ธ, โซ๏ธ ๐ซ๐ ๐ ๐ ๐ฝ.
๐ฅ ๐ ๐ฃ ๐ ๐ ๐ Pydantic ๐ท.
โ๏ธ โฎ๏ธ ๐ ๐ณ, Pydantic โซ๏ธ ๐ ๐ ๐ ๐ฝ โซ๏ธ ๐ช โช๏ธโก๏ธ ๐ข (โฉ๏ธ ๐ค dict), ๐ ๐ช ๐ฃ ๐ฏ ๐ฝ ๐ ๐ ๐จ & โซ๏ธ ๐ ๐ช ๐ถ & ๐ค โซ๏ธ, โช๏ธโก๏ธ ๐.
๐ฉ ๐จ๐ป¶
๐ โก๏ธ ๐ ๐ sql_app/crud.py.
๐ ๐ ๐ฅ ๐ โ๏ธ โป ๐ข ๐ โฎ๏ธ ๐ฝ ๐ฝ.
๐ฉ ๐ โช๏ธโก๏ธ: ๐ ฑ๐ง, โ๐ณ, ๐ค = , & ๐จ๐ฎ๐ง.
...๐ ๐ ๐ผ ๐ฅ ๐ด ๐ & ๐.
โ ๐ฝ¶
๐ Session โช๏ธโก๏ธ sqlalchemy.orm, ๐ ๐ โ ๐ ๐ฃ ๐ db ๐ข & โ๏ธ ๐ป ๐ โ
& ๐ ๏ธ ๐ ๐ข.
๐ models (๐ธ๐ฒ ๐ท) & schemas (Pydantic ๐ท / ๐).
โ ๐ ๐ข:
- โ ๐ ๐ฉโ๐ป ๐ & ๐ง.
- โ ๐ ๐ฉโ๐ป.
- โ ๐ ๐ฌ.
from sqlalchemy.orm import Session
from . import models, schemas
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def get_user_by_email(db: Session, email: str):
return db.query(models.User).filter(models.User.email == email).first()
def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
def create_user(db: Session, user: schemas.UserCreate):
fake_hashed_password = user.password + "notreallyhashed"
db_user = models.User(email=user.email, hashed_password=fake_hashed_password)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
def get_items(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.Item).offset(skip).limit(limit).all()
def create_user_item(db: Session, item: schemas.ItemCreate, user_id: int):
db_item = models.Item(**item.dict(), owner_id=user_id)
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item
Tip
๐ ๐ข ๐ ๐ด ๐ก ๐ โฎ๏ธ ๐ฝ (๐ค ๐ฉโ๐ป โ๏ธ ๐ฌ) ๐ฌ ๐ โก ๐ ๏ธ ๐ข, ๐ ๐ช ๐ ๐ช โป ๐ซ ๐ ๐ & ๐ฎ โ ๐ฏ ๐ซ.
โ ๐ฝ¶
๐ โ ๐ ๐ข โ ๐ฝ.
๐:
- โ ๐ธ๐ฒ ๐ท ๐ โฎ๏ธ ๐ ๐.
add๐ ๐ ๐ ๐ ๐ฝ ๐.commit๐ ๐ฝ (๐ ๐ซ ๐).refresh๐ ๐ (๐ โซ๏ธ ๐ ๐ ๐ ๐ โช๏ธโก๏ธ ๐ฝ, ๐ ๐ ๐).
from sqlalchemy.orm import Session
from . import models, schemas
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def get_user_by_email(db: Session, email: str):
return db.query(models.User).filter(models.User.email == email).first()
def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
def create_user(db: Session, user: schemas.UserCreate):
fake_hashed_password = user.password + "notreallyhashed"
db_user = models.User(email=user.email, hashed_password=fake_hashed_password)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
def get_items(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.Item).offset(skip).limit(limit).all()
def create_user_item(db: Session, item: schemas.ItemCreate, user_id: int):
db_item = models.Item(**item.dict(), owner_id=user_id)
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item
Tip
๐ธ๐ฒ ๐ท User ๐ hashed_password ๐ ๐ ๐ ๐ #๏ธโฃ โฌ ๐.
โ๏ธ โซ๏ธโ ๐ ๏ธ ๐ฉโ๐ป ๐ โฎ๏ธ ๐, ๐ ๐ช โ โซ๏ธ & ๐ #๏ธโฃ ๐ ๐ ๐ธ.
& โคด๏ธ ๐ถโโ๏ธ hashed_password โ โฎ๏ธ ๐ฒ ๐.
Warning
๐ ๐ผ ๐ซ ๐, ๐ ๐ซ#๏ธโฃ.
๐ฐ ๐จโโคโ๐จ ๐ธ ๐ ๐ ๐ช #๏ธโฃ ๐ & ๐ ๐ ๐ซ ๐ข.
๐ โน, ๐ถ ๐ ๐โโ ๐ ๐ฐ.
๐ฅ ๐ฅ ๐ฏ ๐ด ๐ ๐งฐ & ๐จโ๐ง ๐ฝ.
Tip
โฉ๏ธ ๐ถโโ๏ธ ๐ ๐จ๐ป โ Item & ๐ ๐ 1๏ธโฃ ๐ซ โช๏ธโก๏ธ Pydantic ๐ท, ๐ฅ ๐ญ dict โฎ๏ธ Pydantic ๐ท'โ ๐ โฎ๏ธ:
item.dict()
& โคด๏ธ ๐ฅ ๐ถโโ๏ธ dict'โ ๐-๐ฒ ๐ซ ๐จ๐ป โ ๐ธ๐ฒ Item, โฎ๏ธ:
Item(**item.dict())
& โคด๏ธ ๐ฅ ๐ถโโ๏ธ โ ๐จ๐ป โ owner_id ๐ ๐ซ ๐ Pydantic ๐ท, โฎ๏ธ:
Item(**item.dict(), owner_id=user_id)
๐ FastAPI ๐ฑ¶
& ๐ ๐ sql_app/main.py โก๏ธ ๐ ๏ธ & โ๏ธ ๐ ๐ ๐ ๐ฅ โ โญ.
โ ๐ฝ ๐¶
๐ถ ๐ ๐ โ ๐ฝ ๐:
from typing import List
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=list[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
โ ๐¶
๐ ๐ ๐ ๐ฒ ๐ข ๐ ๐ฝ (โ ๐, โ๏ธ) โฎ๏ธ โ.
& ๐ ๐ โ๏ธ โ "๐ ๏ธ" (๐ ๐ฎ ๐ ๐จโ๐ญ).
"๐ ๏ธ" โ ๐ ๐ช ๐โ ๐ ๐ ๐ ๐ ๐ธ๐ฒ ๐ท, ๐ฎ ๐ ๐ข, โ๏ธ. ๐ ๐ ๐ ๐ฝ, ๐ฎ ๐ ๐, ๐ ๐, โ๏ธ.
๐ ๐ช ๐ ๐ผ โ FastAPI ๐ ๐ โช๏ธโก๏ธ ๐ โก - ๐. ๐ฏ alembic ๐ โน ๐.
โ ๐¶
๐ โ๏ธ SessionLocal ๐ ๐ฅ โ sql_app/database.py ๐ โ ๐.
๐ฅ ๐ช โ๏ธ ๐ฌ ๐ฝ ๐/๐ (SessionLocal) ๐ ๐จ, โ๏ธ ๐ ๐ ๐ ๐ ๐จ & โคด๏ธ ๐ โซ๏ธ โฎ๏ธ ๐จ ๐.
& โคด๏ธ ๐ ๐ ๐ โ โญ ๐จ.
๐, ๐ฅ ๐ โ ๐ ๐ โฎ๏ธ yield, ๐ฌ โญ ๐ ๐ ๐ โฎ๏ธ yield.
๐ ๐ ๐ โ ๐ ๐ธ๐ฒ SessionLocal ๐ ๐ โ๏ธ ๐ ๐จ, & โคด๏ธ ๐ โซ๏ธ ๐ ๐จ ๐.
from typing import List
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=list[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
Info
๐ฅ ๐ฎ ๐ SessionLocal() & ๐ ๐จ try ๐ซ.
& โคด๏ธ ๐ฅ ๐ โซ๏ธ finally ๐ซ.
๐ ๐ ๐ฅ โ ๐ญ ๐ฝ ๐ ๐ง ๐ช โฎ๏ธ ๐จ. ๐ฅ ๐ค โ โช ๐ญ ๐จ.
โ๏ธ ๐ ๐ช ๐ซ ๐ค โ1๏ธโฃ โ โช๏ธโก๏ธ ๐ช ๐ (โฎ๏ธ yield). ๐ ๐ ๐ โฎ๏ธ yield & HTTPException
& โคด๏ธ, ๐โ โ๏ธ ๐ โก ๐ ๏ธ ๐ข, ๐ฅ ๐ฃ โซ๏ธ โฎ๏ธ ๐ Session ๐ฅ ๐ ๐ โช๏ธโก๏ธ ๐ธ๐ฒ.
๐ ๐ โคด๏ธ ๐ค ๐ฅ ๐ ๐จโ๐จ ๐โ๐ฆบ ๐ โก ๐ ๏ธ ๐ข, โฉ๏ธ ๐จโ๐จ ๐ ๐ญ ๐ db ๐ข ๐ Session:
from typing import List
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=list[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
๐ก โน
๐ข db ๐ค ๐ SessionLocal, โ๏ธ ๐ ๐ (โ โฎ๏ธ sessionmaker()) "๐ณ" ๐ธ๐ฒ Session,, ๐จโ๐จ ๐ซ ๐ค ๐ญ โซ๏ธโ ๐ฉโ๐ฌ ๐.
โ๏ธ ๐ฃ ๐ Session, ๐จโ๐จ ๐ ๐ช ๐ญ ๐ช ๐ฉโ๐ฌ (.add(), .query(), .commit(), โ๏ธ) & ๐ช ๐ ๐ ๐โ๐ฆบ (๐ ๐ ๏ธ). ๐ ๐ ๐ซ ๐ โ ๐.
โ ๐ FastAPI โก ๐ ๏ธ¶
๐, ๐, ๐ฅ ๐ฉ FastAPI โก ๐ ๏ธ ๐.
from typing import List
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=list[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
๐ฅ ๐ ๐ฝ ๐ โญ ๐ ๐จ ๐ โฎ๏ธ yield, & โคด๏ธ ๐ช โซ๏ธ โฎ๏ธ.
& โคด๏ธ ๐ฅ ๐ช โ ๐ ๐ โก ๐ ๏ธ ๐ข, ๐ค ๐ ๐ ๐.
โฎ๏ธ ๐, ๐ฅ ๐ช ๐ค crud.get_user ๐ โช๏ธโก๏ธ ๐ โก ๐ ๏ธ ๐ข & โ๏ธ ๐ ๐.
Tip
๐ ๐ ๐ฒ ๐ ๐จ ๐ธ๐ฒ ๐ท, โ๏ธ ๐ ๐ธ๐ฒ ๐ท.
โ๏ธ ๐ โก ๐ ๏ธ โ๏ธ response_model โฎ๏ธ Pydantic ๐ท / ๐ โ๏ธ orm_mode, ๐ฝ ๐ฃ ๐ Pydantic ๐ท ๐ โ โช๏ธโก๏ธ ๐ซ & ๐จ ๐ฉโ๐ป, โฎ๏ธ ๐ ๐ โฝ & ๐ฌ.
Tip
๐ ๐ ๐ค response_models ๐ โ๏ธ ๐ฉ ๐ ๐ ๐ List[schemas.Item].
โ๏ธ ๐/๐ข ๐ List Pydantic ๐ท โฎ๏ธ orm_mode, ๐ฝ ๐ ๐ & ๐จ ๐ฉโ๐ป ๐, ๐ต โ .
๐ def ๐ async def¶
๐ฅ ๐ฅ โ๏ธ ๐ธ๐ฒ ๐ ๐ โก ๐ ๏ธ ๐ข & ๐, &, ๐, โซ๏ธ ๐ ๐ถ & ๐ โฎ๏ธ ๐ข ๐ฝ.
๐ ๐ช โ ๐ "โ".
โ๏ธ ๐ธ๐ฒ ๐ซ โ๏ธ ๐ โ๏ธ await ๐, ๐ โฎ๏ธ ๐ณ ๐:
user = await db.query(User).first()
...& โฉ๏ธ ๐ฅ โ๏ธ:
user = db.query(User).first()
โคด๏ธ ๐ฅ ๐ ๐ฃ โก ๐ ๏ธ ๐ข & ๐ ๐ต async def, โฎ๏ธ ๐ def,:
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
...
Info
๐ฅ ๐ ๐ช ๐ ๐ ๐ ๐ฝ ๐, ๐ ๐ ๐ (๐) ๐ฝ.
๐ถ ๐ก โน
๐ฅ ๐ ๐ & โ๏ธ โฌ ๐ก ๐ก, ๐ ๐ช โ
๐ถ ๐ก โน โ ๐ async def ๐ def ๐ต ๐ ๐ฉบ.
๐ ๏ธ¶
โฉ๏ธ ๐ฅ โ๏ธ ๐ธ๐ฒ ๐ & ๐ฅ ๐ซ ๐ ๐ ๐ ๐-โซ๏ธ ๐ท โฎ๏ธ FastAPI, ๐ฅ ๐ช ๐ ๏ธ ๐ฝ ๐ ๏ธ โฎ๏ธ โ ๐.
& ๐ ๐ ๐ธ๐ฒ & ๐ธ๐ฒ ๐ท ๐ ๐ ๐ฌ ๐, ๐ ๐ ๐ช ๐ญ ๐ ๏ธ โฎ๏ธ โ ๐ต โ๏ธ โ FastAPI, Pydantic, โ๏ธ ๐ณ ๐.
๐ ๐, ๐ ๐ ๐ช โ๏ธ ๐ ๐ธ๐ฒ ๐ท & ๐ ๐ ๐ ๐ ๐ ๐ ๐ซ ๐ FastAPI.
๐ผ, ๐ฅ ๐ ๐จโ๐ญ โฎ๏ธ ๐ฅ, ๐ ฟ, โ๏ธ ๐ถ.
๐ ๐ ๐¶
๐ญ ๐ ๐ โ๏ธ ๐ ๐ my_super_project ๐ ๐ ๐ง-๐ ๐ค sql_app.
sql_app ๐ โ๏ธ ๐ ๐:
-
sql_app/__init__.py: ๐ ๐. -
sql_app/database.py:
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "sqlite:///./sql_app.db"
# SQLALCHEMY_DATABASE_URL = "postgresql://user:password@postgresserver/db"
engine = create_engine(
SQLALCHEMY_DATABASE_URL, connect_args={"check_same_thread": False}
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
sql_app/models.py:
from sqlalchemy import Boolean, Column, ForeignKey, Integer, String
from sqlalchemy.orm import relationship
from .database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True)
hashed_password = Column(String)
is_active = Column(Boolean, default=True)
items = relationship("Item", back_populates="owner")
class Item(Base):
__tablename__ = "items"
id = Column(Integer, primary_key=True, index=True)
title = Column(String, index=True)
description = Column(String, index=True)
owner_id = Column(Integer, ForeignKey("users.id"))
owner = relationship("User", back_populates="items")
sql_app/schemas.py:
from typing import List, Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: List[Item] = []
class Config:
orm_mode = True
from typing import Union
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: Union[str, None] = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
from pydantic import BaseModel
class ItemBase(BaseModel):
title: str
description: str | None = None
class ItemCreate(ItemBase):
pass
class Item(ItemBase):
id: int
owner_id: int
class Config:
orm_mode = True
class UserBase(BaseModel):
email: str
class UserCreate(UserBase):
password: str
class User(UserBase):
id: int
is_active: bool
items: list[Item] = []
class Config:
orm_mode = True
sql_app/crud.py:
from sqlalchemy.orm import Session
from . import models, schemas
def get_user(db: Session, user_id: int):
return db.query(models.User).filter(models.User.id == user_id).first()
def get_user_by_email(db: Session, email: str):
return db.query(models.User).filter(models.User.email == email).first()
def get_users(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.User).offset(skip).limit(limit).all()
def create_user(db: Session, user: schemas.UserCreate):
fake_hashed_password = user.password + "notreallyhashed"
db_user = models.User(email=user.email, hashed_password=fake_hashed_password)
db.add(db_user)
db.commit()
db.refresh(db_user)
return db_user
def get_items(db: Session, skip: int = 0, limit: int = 100):
return db.query(models.Item).offset(skip).limit(limit).all()
def create_user_item(db: Session, item: schemas.ItemCreate, user_id: int):
db_item = models.Item(**item.dict(), owner_id=user_id)
db.add(db_item)
db.commit()
db.refresh(db_item)
return db_item
sql_app/main.py:
from typing import List
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
from fastapi import Depends, FastAPI, HTTPException
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
# Dependency
def get_db():
db = SessionLocal()
try:
yield db
finally:
db.close()
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=list[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
โ โซ๏ธ¶
๐ ๐ช ๐ ๐ ๐ & โ๏ธ โซ๏ธ.
Info
๐, ๐ ๐ฆ ๐ฅ ๐ ๐ฏ. ๐ ๐ ๐ ๐ฉบ.
โคด๏ธ ๐ ๐ช ๐ โซ๏ธ โฎ๏ธ Uvicorn:
$ uvicorn sql_app.main:app --reload
<span style="color: green;">INFO</span>: Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
& โคด๏ธ, ๐ ๐ช ๐ ๐ ๐ฅ http://127.0.0.1:8000/docs.
& ๐ ๐ ๐ช ๐ โฎ๏ธ ๐ FastAPI ๐ธ, ๐ ๐ โช๏ธโก๏ธ ๐ฐ ๐ฝ:

๐ โฎ๏ธ ๐ฝ ๐¶
๐ฅ ๐ ๐ ๐ฌ ๐ ๐ฝ (๐) ๐, โก FastAPI, โน ๐ฎ ๐, ๐ฎ ๐, ๐, โบ, ๐ ๐, โ๏ธ. ๐ ๐ช โ๏ธ ๐ฝ ๐ฅ ๐.
โซ๏ธ ๐ ๐ ๐ ๐:

๐ ๐ช โ๏ธ ๐ณ ๐ ๐ฅ ๐ ๐ ๐ โ๏ธ ExtendsClass.
๐ ๐ฝ ๐ โฎ๏ธ ๐ ๏ธ¶
๐ฅ ๐ ๐ช ๐ซ โ๏ธ ๐ โฎ๏ธ yield - ๐ผ, ๐ฅ ๐ ๐ซ โ๏ธ ๐ 3๏ธโฃ.7๏ธโฃ & ๐ช ๐ซ โ "๐" ๐ค ๐ ๐ 3๏ธโฃ.6๏ธโฃ - ๐ ๐ช โ ๐ ๐ "๐ ๏ธ" ๐ ๐.
"๐ ๏ธ" ๐ ๐ข ๐ ๐ง ๐ ๏ธ ๐ ๐จ, โฎ๏ธ ๐ ๐ ๏ธ โญ, & ๐ ๐ ๏ธ โฎ๏ธ ๐ ๐ข.
โ ๐ ๏ธ¶
๐ ๏ธ ๐ฅ ๐ ๐ฎ (๐ข) ๐ โ ๐ ๐ธ๐ฒ SessionLocal ๐ ๐จ, ๐ฎ โซ๏ธ ๐จ & โคด๏ธ ๐ โซ๏ธ ๐ ๐จ ๐.
from typing import List
from fastapi import Depends, FastAPI, HTTPException, Request, Response
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
@app.middleware("http")
async def db_session_middleware(request: Request, call_next):
response = Response("Internal server error", status_code=500)
try:
request.state.db = SessionLocal()
response = await call_next(request)
finally:
request.state.db.close()
return response
# Dependency
def get_db(request: Request):
return request.state.db
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=List[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=List[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
from fastapi import Depends, FastAPI, HTTPException, Request, Response
from sqlalchemy.orm import Session
from . import crud, models, schemas
from .database import SessionLocal, engine
models.Base.metadata.create_all(bind=engine)
app = FastAPI()
@app.middleware("http")
async def db_session_middleware(request: Request, call_next):
response = Response("Internal server error", status_code=500)
try:
request.state.db = SessionLocal()
response = await call_next(request)
finally:
request.state.db.close()
return response
# Dependency
def get_db(request: Request):
return request.state.db
@app.post("/users/", response_model=schemas.User)
def create_user(user: schemas.UserCreate, db: Session = Depends(get_db)):
db_user = crud.get_user_by_email(db, email=user.email)
if db_user:
raise HTTPException(status_code=400, detail="Email already registered")
return crud.create_user(db=db, user=user)
@app.get("/users/", response_model=list[schemas.User])
def read_users(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
users = crud.get_users(db, skip=skip, limit=limit)
return users
@app.get("/users/{user_id}", response_model=schemas.User)
def read_user(user_id: int, db: Session = Depends(get_db)):
db_user = crud.get_user(db, user_id=user_id)
if db_user is None:
raise HTTPException(status_code=404, detail="User not found")
return db_user
@app.post("/users/{user_id}/items/", response_model=schemas.Item)
def create_item_for_user(
user_id: int, item: schemas.ItemCreate, db: Session = Depends(get_db)
):
return crud.create_user_item(db=db, item=item, user_id=user_id)
@app.get("/items/", response_model=list[schemas.Item])
def read_items(skip: int = 0, limit: int = 100, db: Session = Depends(get_db)):
items = crud.get_items(db, skip=skip, limit=limit)
return items
Info
๐ฅ ๐ฎ ๐ SessionLocal() & ๐ ๐จ try ๐ซ.
& โคด๏ธ ๐ฅ ๐ โซ๏ธ finally ๐ซ.
๐ ๐ ๐ฅ โ ๐ญ ๐ฝ ๐ ๐ง ๐ช โฎ๏ธ ๐จ. ๐ฅ ๐ค โ โช ๐ญ ๐จ.
๐ request.state¶
request.state ๐ ๐ Request ๐. โซ๏ธ ๐ค ๐ช โ ๐ ๐ ๐จ โซ๏ธ, ๐ ๐ฝ ๐ ๐ ๐ผ. ๐ ๐ช โ ๐
๐ โซ๏ธ ๐ ๐ฉบ ๐ Request ๐ต๐ธ.
๐ฅ ๐ ๐ผ, โซ๏ธ โน ๐ฅ ๐ ๐ ๐ฝ ๐ โ๏ธ ๐ ๐ ๐จ, & โคด๏ธ ๐ โฎ๏ธ (๐ ๏ธ).
๐ โฎ๏ธ yield โ๏ธ ๐ ๏ธ¶
โ ๐ ๏ธ ๐ฅ ๐ โซ๏ธโ ๐ โฎ๏ธ yield ๐จ, โฎ๏ธ ๐บ:
- โซ๏ธ ๐ ๐ ๐ & ๐ ๐ ๐.
- ๐ ๏ธ โ๏ธ
async๐ข.- ๐ฅ ๐ค ๐ โซ๏ธ ๐ โ๏ธ "โ" ๐ธ, โซ๏ธ ๐ช "๐ซ" ๐ ๐ธ ๐ค & ๐ ๐ญ ๐.
- ๐ โซ๏ธ ๐ฒ ๐ซ ๐ถ โ ๐ฅ โฎ๏ธ ๐
SQLAlchemy๐ท. - โ๏ธ ๐ฅ ๐ ๐ฎ ๐ ๐ ๐ ๏ธ ๐ โ๏ธ ๐ ๐ค/๐ พ โ, โซ๏ธ ๐ช โคด๏ธ โ .
- ๐ ๏ธ ๐ ๐ ๐จ.
- , ๐ ๐ โ ๐ ๐จ.
- ๐โ โก ๐ ๏ธ ๐ ๐ต ๐ ๐จ ๐ซ ๐ช ๐ฝ.
Tip
โซ๏ธ ๐ฒ ๐ โ๏ธ ๐ โฎ๏ธ yield ๐โ ๐ซ ๐ฅ โ๏ธ ๐ผ.
Info
๐ โฎ๏ธ yield ๐ฎ โณ FastAPI.
โฎ๏ธ โฌ ๐ ๐ฐ ๐ด โ๏ธ ๐ผ โฎ๏ธ ๐ ๏ธ & ๐ค ๐ฒ ๐ ๐ธ โ๏ธ ๐ ๏ธ ๐ฝ ๐ ๐งพ.