Skip to content

๐Ÿ—„ (๐Ÿ”—) ๐Ÿ’ฝ

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.

โฎ๏ธ โฌ ๐Ÿ‘‰ ๐Ÿ”ฐ ๐Ÿ•ด โœ”๏ธ ๐Ÿ–ผ โฎ๏ธ ๐Ÿ› ๏ธ & ๐Ÿ“ค ๐ŸŽฒ ๐Ÿ“š ๐Ÿˆธ โš™๏ธ ๐Ÿ› ๏ธ ๐Ÿ’ฝ ๐ŸŽ‰ ๐Ÿงพ.