๐ (๐) ๐ฝ¶
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.
โฎ๏ธ โฌ ๐ ๐ฐ ๐ด โ๏ธ ๐ผ โฎ๏ธ ๐ ๏ธ & ๐ค ๐ฒ ๐ ๐ธ โ๏ธ ๐ ๏ธ ๐ฝ ๐ ๐งพ.