
рд╢реБрдн рджрд┐рди
рдЖрдЬ рдореИрдВ ORM SQLAlchemy рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдмрд╛рдд рдХрд░рдирд╛ рдЪрд╛рд╣рддрд╛ рд╣реВрдВред рдЖрдЗрдП рдмрд╛рдд рдХрд░рддреЗ рд╣реИрдВ рдХрд┐ рдпрд╣ рдЕрдкрдиреА рдХреНрд╖рдорддрд╛рдУрдВ рдФрд░ рд▓рдЪреАрд▓реЗрдкрди рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдХреНрдпрд╛ рд╣реИ, рдФрд░ рдЙрди рдорд╛рдорд▓реЛрдВ рдкрд░ рднреА рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВ рдЬреЛ рд╣рдореЗрд╢рд╛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рд╡рд░реНрдгрд┐рдд рдирд╣реАрдВ рд╣реИрдВред
рдЗрд╕ рдУрдЖрд░рдПрдо рдореЗрдВ рдФрд╕рдд рд╕реЗ рдКрдкрд░ рдкреНрд░рд╡реЗрд╢ рдХреА рд╕реАрдорд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдореИрдВ рдПрдХ рд╕рд░рд▓ рднрд╛рд╖рд╛ рдореЗрдВ рдФрд░ рдЙрджрд╛рд╣рд░рдгреЛрдВ рдХреЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рд╕рдордЭрд╛рдиреЗ рдХреА рдХреЛрд╢рд┐рд╢ рдХрд░реВрдВрдЧрд╛ред рдпрд╣ рд▓реЗрдЦ рдЙрди рд▓реЛрдЧреЛрдВ рдХреЗ рд▓рд┐рдП рдЙрдкрдпреЛрдЧреА рд╣реЛрдЧрд╛, рдЬреЛ рдкрд╣рд▓реЗ рд╕реЗ рд╣реА рд╕реНрдХреНрд╡рд▓рдХреЗрдо рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЕрдкрдиреЗ рдХреМрд╢рд▓ рдХреЛ рдЕрдкрдЧреНрд░реЗрдб рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ рдпрд╛ рдмрд╕ рдЗрд╕ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдкрд░рд┐рдЪрд┐рдд рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
рдЙрдкрдпреЛрдЧ рдХреА рдЧрдИ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдкрд╛рдпрдерди 3.6 рд╣реИред
DB - PostgreSQLред
рдЬреАрдердм рд▓рд┐рдВрдХ
рддреЛ ORM рдХреНрдпрд╛ рд╣реИ?
ORM (рдСрдмреНрдЬреЗрдХреНрдЯ-рд░рд┐рд▓реЗрд╢рдирд▓ рдореИрдкрд┐рдВрдЧ) рдПрдХ рдРрд╕реА рддрдХрдиреАрдХ рд╣реИ рдЬреЛ рдЖрдкрдХреЛ рдЙрди рдореЙрдбрд▓реЛрдВ рдХреЛ рдореИрдк рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддреА рд╣реИ рдЬрд┐рдирдХреЗ рдкреНрд░рдХрд╛рд░ рдЕрд╕рдВрдЧрдд рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП: рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдФрд░ рдПрдХ рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рднрд╛рд╖рд╛ рдСрдмреНрдЬреЗрдХреНрдЯред
рджреВрд╕рд░реЗ рд╢рдмреНрджреЛрдВ рдореЗрдВ, рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рдЯреЗрдмрд▓ рдореЗрдВ рдбреЗрдЯрд╛ рдХреЛ рдкреНрд░рдмрдВрдзрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХреНрд▓рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯ рддрдХ рдкрд╣реБрдВрдЪ рд╕рдХрддреЗ рд╣реИрдВред рдЖрдк рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдХреЗ рд▓рд┐рдП рдореИрдк рдХреА рдЧрдИ, рд╕рдмрд╕реЗ рдорд╣рддреНрд╡рдкреВрд░реНрдг рдмрд╛рдд, рдЗрдирд╣реЗрд░рд┐рдЯ рдХреНрд▓рд╛рд╕ рдСрдмреНрдЬреЗрдХреНрдЯреНрд╕ рдмрдирд╛ рд╕рдХрддреЗ рд╣реИрдВ, рд╕рдВрд╢реЛрдзрд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рд╣рдЯрд╛ рд╕рдХрддреЗ рд╣реИрдВ, рдЬреЛ рдХреЛрдб рдмреЗрд╕ рдХреА рд╕рд╛рдордЧреНрд░реА рдХреЛ рдХрд╛рдлреА рдХрдо рдХрд░ рджреЗрддрд╛ рд╣реИред
SQLAlchemy рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред
рдЬреЛ рдбреЗрд╡рд▓рдкрд░реНрд╕ Django-ORM рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВ, рдЙрдиреНрд╣реЗрдВ ORM рдХреНрд╡реЗрд░реА рдмрдирд╛рдиреЗ рдХреЗ рд▓рд┐рдП рдЕрдкрдиреА рдорд╛рдирд╕рд┐рдХрддрд╛ рдХреЛ рдереЛрдбрд╝рд╛ рдкреБрдирд░реНрдирд┐рд░реНрдорд╛рдг рдХрд░рдирд╛ рд╣реЛрдЧрд╛ред рдореЗрд░реА рд░рд╛рдп рдореЗрдВ, SQLAlchemy рдПрдХ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд░рд╛рдХреНрд╖рд╕ рд╣реИ рдЬрд┐рд╕рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХрд╛ рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдФрд░ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЪрд╛рд╣рд┐рдП, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдпрд╣ рд╕рдордЭрдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ рдХрд┐ ORM рд╣рдореЗрд╢рд╛ рд╕рд╣реА рдирд╣реАрдВ рд╣реЛрддреЗ рд╣реИрдВред рдЗрд╕рд▓рд┐рдП, рд╣рдо рдЙрди рдХреНрд╖рдгреЛрдВ рдкрд░ рдЪрд░реНрдЪрд╛ рдХрд░реЗрдВрдЧреЗ рдЬрдм рдЗрд╕ рддрдХрдиреАрдХ рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрдЪрд┐рдд рд╣реЛрдЧрд╛ред
SQLAlchemy рдореЗрдВ рдШреЛрд╖рдгрд╛рддреНрдордХ рдФрд░ рдЧреИрд░-рдШреЛрд╖рдгрд╛рддреНрдордХ рдореЙрдбрд▓ рдкрд░рд┐рднрд╛рд╖рд╛рдУрдВ рдХреА рдЕрд╡рдзрд╛рд░рдгрд╛ рд╣реИред
рдЧреИрд░-рдШреЛрд╖рдгрд╛рддреНрдордХ рдкрд░рд┐рднрд╛рд╖рд╛ рдореЗрдВ рдореИрдкрд░ () рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реЛрддрд╛ рд╣реИ, рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЙрд▓рдо рдФрд░ рдореЙрдбрд▓ рд╡рд░реНрдЧ рдХреЗ рдорд╛рдирдЪрд┐рддреНрд░рдг рдХрд╛ рд╡рд░реНрдгрди рдХрд░рддрд╛ рд╣реИред
рдпрд╣ рдЖрд▓реЗрдЦ рдореЙрдбрд▓ рдХреА рдПрдХ рдШреЛрд╖рдгрд╛рддреНрдордХ рдкрд░рд┐рднрд╛рд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддрд╛ рд╣реИред
рдпрд╣рд╛рдБ рдФрд░
DB рд╕рдВрд░рдЪрдирд╛
рдкреВрд░реНрдг рдбреЗрдЯрд╛ рд╕рдВрдЧрддрд┐ рдХреЗ рд▓рд┐рдП, рдЖрдЗрдП рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рддрд╛рд▓рд┐рдХрд╛рдПрдБ рдмрдирд╛рдПрдБред
рдореВрд▓ рдореЙрдбрд▓ рдХрд╛ рдЙрдкрдпреЛрдЧ рдбреЗрдЯрд╛рдмреЗрд╕ рдореЗрдВ рдореВрд▓ рд╕реНрддрдВрднреЛрдВ рдХреЛ рдирд┐рд░реНрдзрд╛рд░рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
class BaseModel(Base): __abstract__ = True id = Column(Integer, nullable=False, unique=True, primary_key=True, autoincrement=True) created_at = Column(TIMESTAMP, nullable=False) updated_at = Column(TIMESTAMP, nullable=False) def __repr__(self): return "<{0.__class__.__name__}(id={0.id!r})>".format(self)
рдХрд░реНрдордЪрд╛рд░реА - рдХрд╛рд░реНрдпрд╛рд▓рдп рдореЗрдВ рдХрд╛рдо рдХрд░рдиреЗ рд╡рд╛рд▓реЗ рдХрд░реНрдордЪрд╛рд░реА рдХрд╛ рд╡рд░реНрдгрди рдХрд░рдиреЗ рд╡рд╛рд▓реА рдПрдХ рддрд╛рд▓рд┐рдХрд╛
class Employee(BaseModel): __tablename__ = 'employees' first_name = Column(VARCHAR(255), nullable=False) last_name = Column(VARCHAR(255), nullable=False) phone = Column(VARCHAR(255), unique=True, nullable=True) description = Column(VARCHAR(255), nullable=True)
EmployeeWithSkills рдПрдХ рддрд╛рд▓рд┐рдХрд╛ рдирд╣реАрдВ рд╣реИред рд╡рд░реНрдЧ рдХрд░реНрдордЪрд╛рд░реА рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ред рддрд░реНрдХ рдХреЛ рдЕрд▓рдЧ рдХрд░рдиреЗ рдФрд░ рдХрдХреНрд╖рд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХрд╛ рдПрдХ рд╢рд╛рдирджрд╛рд░ рдЕрд╡рд╕рд░ рдЬреИрд╕реЗ рдХрд┐ рдпрд╣ рдПрдХ рдЕрд▓рдЧ рддрд╛рд▓рд┐рдХрд╛ рдереАред
class EmployeeWithSkills(Employee): skills = relation(Skill, secondary=EmployeesSkills.__tablename__, lazy='joined')
рд╡рд┐рднрд╛рдЧ - рд╡рд╣ рд╡рд┐рднрд╛рдЧ рдЬрд┐рд╕рдореЗрдВ рдпрд╣ рдХрд░реНрдордЪрд╛рд░реА рдХрд╛рдо рдХрд░рддрд╛ рд╣реИред рдПрдХ рд╡реНрдпрдХреНрддрд┐ рдореЗрдВ рдХрдИ рд╡рд┐рднрд╛рдЧ рд╢рд╛рдорд┐рд▓ рд╣реЛ рд╕рдХрддреЗ рд╣реИрдВред
class Department(BaseModel): __tablename__ = 'departments' name = Column(VARCHAR(255), nullable=False) description = Column(VARCHAR(255), nullable=False)
рдХрд░реНрдордЪрд╛рд░реА рдФрд░ рдЗрдХрд╛рдЗрдпреЛрдВ рдХрд╛ рдкрддреНрд░рд╛рдЪрд╛рд░ рддрд╛рд▓рд┐рдХрд╛ рдЬрд┐рд╕рдореЗрдВ рд╡рд╣ рдПрдХ рд╕рджрд╕реНрдп рд╣реИред
class EmployeeDepartments(BaseModel): __tablename__ = 'employee_departments' employee_id = Column(Integer, ForeignKey('employees.id', ondelete='CASCADE'), nullable=False, index=True) department_id = Column(Integer, ForeignKey('departments.id', ondelete='CASCADE'), nullable=False, index=True)
рдХрд░реНрдордЪрд╛рд░рд┐рдпреЛрдВ рдФрд░ рдЙрдирдХреЗ рдХреМрд╢рд▓ рдХреА рдкрддреНрд░рд╛рдЪрд╛рд░ рддрд╛рд▓рд┐рдХрд╛ред
class EmployeesSkills(BaseModel): __tablename__ = 'employees_skills' employee_id = Column(ForeignKey('employee.id', ondelete='CASCADE'), nullable=False, index=True) skill_id = Column(ForeignKey('skills.id', ondelete='CASCADE'), nullable=False, index=True)
рд╣рдо рдПрд▓реЗрдореНрдмрд┐рдХ рдкреИрдХреЗрдЬ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдмрдирд╛рддреЗ рд╣реИрдВ, рдЬреЛ рдЖрдкрдХреЛ рд╕реНрд╡рдЪрд╛рд▓рд┐рдд рд░реВрдк рд╕реЗ рдЙрддреНрдкрдиреНрди рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред рдЗрд╕ рдкрд╛рда рдореЗрдВ, рдСрдЯреЛ-рдЬрдирд░реЗрд╢рди рдСрдл рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдкреВрд░реА рддрд░рд╣ рд╕реЗ рд╕реНрд╡реАрдХрд╛рд░реНрдп рд╣реИред
рдирд╡реАрдирддрдо рдорд╛рдЗрдЧреНрд░реЗрд╢рди рдореЗрдВ рдкрд░реАрдХреНрд╖рдг рдбреЗрдЯрд╛ рд╣реЛрддрд╛ рд╣реИ рдЬреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рдХреЛ рднрд░ рджреЗрдЧрд╛ред
рдПрд▓реЗрдореНрдмрд┐рдХ рдХреЛ рдХреИрд╕реЗ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░ рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ рдпрд╣рд╛рдВ рдкрдврд╝рд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
рд╣рдо рдкреНрд░рд╡рд╛рд╕ рдХреЛ рдЕрдВрдЬрд╛рдо рджреЗрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╝реАрдорддреА рдФрд▓реАрдорд┐рдХ рдЕрдкрдЧреНрд░реЗрдб рд╣реЗрдб рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред
рдЕрдиреБрд░реЛрдз рдФрд░ рд╕рдВрдмрдВрдз
рдЖрдЗрдП рдкрд╣рд▓реЗ рдЕрдиреБрд░реЛрдз рдХрд░реЗрдВ рдФрд░ рдХрд░реНрдордЪрд╛рд░реА рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ рдЙрд╕рдХреА рдЖрдИрдбреА рд╕реЗ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░реЗрдВред
рдЕрдиреБрд░реЛрдз рдЗрд╕ рддрд░рд╣ рджрд┐рдЦреЗрдЧрд╛:
lesson1:
employee = session.query(Employee).filter(Employee.id == eid).one() output: ID: 2, Tony Stark
.one()
рдЕрдВрдд рдореЗрдВ рдЗрд╕рдХрд╛ рдорддрд▓рдм рд╣реИ рдХрд┐ рд╣рдо рдХреЗрд╡рд▓ рдПрдХ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХрд╛ рдЗрд░рд╛рджрд╛ рд░рдЦрддреЗ рд╣реИрдВред рдпрджрд┐ рдХрдИ рдкреНрд░рд╡рд┐рд╖реНрдЯрд┐рдпрд╛рдБ рд╣реИрдВ, рддреЛ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдЕрдкрд╡рд╛рдж рдЙрдард╛рдпрд╛ рдЬрд╛рдПрдЧрд╛ред
рдпрджрд┐ рд╣рдо рд╕рднреА рдЙрдкрд▓рдмреНрдз рд╡рд┐рднрд╛рдЧреЛрдВ рдХреЛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рд╣рдо .all()
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдХреНрд╡реЗрд░реА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
lesson2:
emmployee = session.query(Department).all() output: ID: 2, name: Guards ID: 4, name: Legions
рдПрдХрддреНрд░реАрдХрд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред
рд╣рдо рдЕрдВрддрд░реНрдирд┐рд╣рд┐рдд рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЙрдкрд▓рдмреНрдз рд╡рд┐рднрд╛рдЧреЛрдВ рдХреА рд╕рдВрдЦреНрдпрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
.count()
рдпрд╛ .count()
рдЙрдкрдпреЛрдЧ рдХрд░реЗрдВред рджреВрд╕рд░реА рд╡рд┐рдзрд┐ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рдЖрдк рдХрд┐рд╕реА рднреА SQL рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдпрд╛ рддреЛ select
рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдпрд╛ рдордзреНрдпрд╡рд░реНрддреА рдкрд░рд┐рдгрд╛рдореЛрдВ рдХреА рдЧрдгрдирд╛ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
lesson3:
def get_departments_count(session: DBSession) -> int: count = session.query(Department).count() return count def get_departments_func_count(session: DBSession) -> int: count = session.query(func.count(Department.id)).scalar() return count
рдХрдИ рдбреЗрд╡рд▓рдкрд░реНрд╕ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдбреЗрдЯрд╛ рдХреА рдЬрд╛рдВрдЪ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП count()
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рдпрд╣ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЕрднреНрдпрд╛рд╕ рдирд╣реАрдВ рд╣реИ, рдЬрд┐рд╕рд╕реЗ рдЕрддрд┐рд░рд┐рдХреНрдд рдбреЗрдЯрд╛рдмреЗрд╕ рд╕рдВрд╕рд╛рдзрдиреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рд╣реЛрддрд╛ рд╣реИ рдФрд░ рдХреНрд╡реЗрд░реА рдирд┐рд╖реНрдкрд╛рджрди рд╕рдордп рдмрдврд╝рддрд╛ рд╣реИред рдПрдХ рдЕрдЪреНрдЫрд╛ рд╕рдорд╛рдзрд╛рди exists()
рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЬреЛ рдПрдХ рд╕реНрдХреЗрд▓рд░ рдорд╛рди рд▓реМрдЯрд╛рддрд╛ рд╣реИ:
lesson3:
def check_department_exists(session: DBSession, department_name: str) -> bool: is_exists = session.query(exists().where(Department.name == department_name)).scalar() return is_exists
рдЖрдЧреЗ рдмрдврд╝рддреЗ рд╣реБрдП, рд╣рдо рдХрд╛рд░реНрдп рдХреЛ рдЬрдЯрд┐рд▓ рдХрд░рддреЗ рд╣реИрдВ рдФрд░ рдЗрдХрд╛рдИ relation
рдпрд╛ relationship
рдкрд░рд┐рдЪрд┐рдд рд╣реЛрддреЗ рд╣реИрдВред рддрдереНрдп рдпрд╣ рд╣реИ рдХрд┐ SQLAlchemy
рд╡рд┐рджреЗрд╢реА_рдХреА рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдХреЗ рдЕрд▓рд╛рд╡рд╛
рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реНрддрд░ рдкрд░, рд╡рд╕реНрддреБрдУрдВ рдХреЗ рдмреАрдЪ рд╕рдВрдмрдВрдзреЛрдВ рдХрд╛ рднреА рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕ рдкреНрд░рдХрд╛рд░, рд╣рдо рдбреЗрдЯрд╛рдмреЗрд╕ рдкрдВрдХреНрддрд┐ рдХреЛ рдСрдмреНрдЬреЗрдХреНрдЯ рдореЗрдВ рд╡рд┐рджреЗрд╢реА рдХреБрдВрдЬреА рдкрд░ рдирд┐рд░реНрднрд░ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдпреЗ рдСрдмреНрдЬреЗрдХреНрдЯ рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛рдУрдВ рдкрд░ рдПрдХ рдкреНрд░рдХреНрд╖реЗрдкрдг рд╣реИрдВ, рдкрд░рд╕реНрдкрд░ рдЬреБрдбрд╝реЗ рд╣реБрдП рд╣реИрдВред
SQLAlchemy
рдореЗрдВ Relations
рдХрд╛ рдПрдХ рд▓рдЪреАрд▓рд╛ рд╡рд┐рдиреНрдпрд╛рд╕ рд╣реИ, рдЬреЛ рдЖрдкрдХреЛ рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рддрд░реАрдХреЛрдВ рд╕реЗ рдЕрд▓рдЧ-рдЕрд▓рдЧ рд╕рдордп рдкрд░ рдирд╛рдорд┐рдд рддрд░реНрдХ lazy
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
"рдЖрд▓рд╕реНрдп" рдХреА рдореБрдЦреНрдп рдбрд┐рдЧреНрд░реА:
select
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╣реИред ORM рдХреЗрд╡рд▓ рдбреЗрдЯрд╛ рдПрдХреНрд╕реЗрд╕ рдХрд░рддреЗ рд╕рдордп рдПрдХ рдЕрдиреБрд░реЛрдз рдХрд░рддрд╛ рд╣реИред рдпрд╣ рдПрдХ рдЕрд▓рдЧ рдЕрдиреБрд░реЛрдз рдореЗрдВ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИредdynamic
- рдЖрдкрдХреЛ рдЕрдиреБрд░реЛрдз рдСрдмреНрдЬреЗрдХреНрдЯ рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬрд┐рд╕реЗ рд╡рд╛рдВрдЫрд┐рдд рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрд╢реЛрдзрд┐рдд рдХрд┐рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИред рдпрд╣ рд╕рднреА () рдпрд╛ рдПрдХ () рдпрд╛ рдХрд┐рд╕реА рднреА рдЕрдиреНрдп рдЙрдкрд▓рдмреНрдз рддрд░реАрдХреЛрдВ рдХреЛ рдХреЙрд▓ рдХрд░рдиреЗ рдХреЗ рдмрд╛рдж рд╣реА рдбреЗрдЯрд╛рдмреЗрд╕ рд╕реЗ рдбреЗрдЯрд╛ рдкреНрд░рд╛рдкреНрдд рдХрд░рддрд╛ рд╣реИредjoined
- LEFT JOIN рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдореБрдЦреНрдп рдЕрдиреБрд░реЛрдз рдореЗрдВ рдЬреЛрдбрд╝рд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕реЗ рддреБрд░рдВрдд рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИредsubquery
- рдЪрдпрди рдХреЗ рд╕рдорд╛рди, рд▓реЗрдХрд┐рди рдЙрдкрд╢реНрд░реЗрдгреА рдХреЗ рд░реВрдк рдореЗрдВ рдирд┐рд╖реНрдкрд╛рджрд┐рддред
рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдХрд╛ select
ред
рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рдЫрд╛рдирдирд╛ рд╕реНрдерд┐рд░ рдФрд░ рдЧрддрд┐рд╢реАрд▓ рд╣реЛ рд╕рдХрддрд╛ рд╣реИред рдбрд╛рдпрдирд╛рдорд┐рдХ рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЗ рд╕рд╛рде рдЕрдиреБрд░реЛрдз рдХреЛ рднрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИ, рдЬреЛ рдлрд╝рдВрдХреНрд╢рди рдХреА рдкреНрд░рдЧрддрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рднрд┐рдиреНрди рд╣реЛ рд╕рдХрддрд╛ рд╣реИред
lesson4:
def dynamic_filter(session: DBSession, filter: DFilter = None): query = session.query(Employee) if filter is not None: query = query.filter(*filter.conds) employees = query.all() return employees
DFilter рдлрд╝рд┐рд▓реНрдЯрд░ рд╡рд░реНрдЧ рдХрд┐рд╕реА рднреА рдЗрдирдкреБрдЯ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдлрд╝рд┐рд▓реНрдЯрд░ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рддрд╛ рд╣реИред рдпрджрд┐ рдлрд╝рд┐рд▓реНрдЯрд░ рд╡рд░реНрдЧ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓реЗрдХрд┐рди рдЕрдиреБрд░реЛрдз рд╢рд░реНрддреЛрдВ рдореЗрдВ рдЖрдЧреЗ рд▓рд╛рдЧреВ рд╣реЛрддрд╛ рд╣реИред
.Filter () рдлрд╝рдВрдХреНрд╢рди SQLAlchemy рдмрд╛рдЗрдирд░реА рд╢рд░реНрддреЛрдВ рдХреЛ рд╕реНрд╡реАрдХрд╛рд░ рдХрд░рддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдЗрд╕реЗ * рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рджрд┐рдЦрд╛рдпрд╛ рдЬрд╛ рд╕рдХрддрд╛ рд╣реИ
рдЧрддрд┐рд╢реАрд▓ рдлрд┐рд▓реНрдЯрд░ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХреЗрд╡рд▓ рдХрд▓реНрдкрдирд╛ рджреНрд╡рд╛рд░рд╛ рд╕реАрдорд┐рдд рд╣реИред рдХреНрд╡реЗрд░реА рдХреЗ рдкрд░рд┐рдгрд╛рдо рд╕реЗ рдкрддрд╛ рдЪрд▓рддрд╛ рд╣реИ рдХрд┐ рд╡рд░реНрддрдорд╛рди рдореЗрдВ рдХреМрди рд╕реЗ рдирд╛рдпрдХ рдирд┐рд╖реНрдХреНрд░рд┐рдп рд╣реИрдВред
output: Inactive_heros: Name: Tony Stark Name: Scott Lang Name: Peter Parker
рдореИрдВ рдХрдИ-рдХрдИ рд╕рдВрдмрдВрдзреЛрдВ рдХреЗ рд╕рд╛рде рдХрд╛рдо рдХрд░рдиреЗ рдХрд╛ рд╕реБрдЭрд╛рд╡ рджреЗрддрд╛ рд╣реВрдВред
рд╣рдорд╛рд░реЗ рдкрд╛рд╕ рдПрдХ рдПрдореНрдкреНрд▓реЙрдИ рдЯреЗрдмрд▓ рд╣реИ рдЬрд┐рд╕рдореЗрдВ рдПрдВрдкреНрд▓реЙрдпреАрдЬрд╕реНрдХрд┐рд▓реНрд╕ рдкрддреНрд░рд╛рдЪрд╛рд░ рдЯреЗрдмрд▓ рд╕реЗ рд╕рдВрдмрдВрдз рд╣реИред рдЗрд╕рдореЗрдВ рдХрд░реНрдордЪрд╛рд░реА рдЯреЗрдмрд▓ рдкрд░ рд╡рд┐рджреЗрд╢реА_рдХреА рдФрд░ рд╡рд┐рджреЗрд╢реА_рдХреА рд╢рд╛рдорд┐рд▓ рд╣реИ
рдХреМрд╢рд▓ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд▓рд┐рдПред
рд╕рдмрдХ 5:
def get_employee_with_skills(session: DBSession, eid: int): employee = session.query(EmployeeWithSkills).filter(EmployeeWithSkills.id == eid).one() return employee output: Employee Tony Stark has skills: Skill: Fly, Desc: I belive I can Fly. I belive I can touch the sky Skill: Light Shield, Desc: Light protect. Perfect for everything
рдЙрдкрд░реЛрдХреНрдд рдХреНрд╡реЗрд░реА рдореЗрдВ EmployeeWithSkills рд╡рд░реНрдЧ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реБрдП, рд╣рдо рдЗрд╕реЗ рдПрдХ рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рд░реВрдк рдореЗрдВ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддреЗ рд╣реИрдВ, рд▓реЗрдХрд┐рди рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдРрд╕реА рдХреЛрдИ рддрд╛рд▓рд┐рдХрд╛ рдореМрдЬреВрдж рдирд╣реАрдВ рд╣реИред рдпрд╣ рд╡рд░реНрдЧ рдПрдХ рд╕рдВрдмрдВрдз рд░рдЦрдиреЗ рд╡рд╛рд▓реЗ рдХрд░реНрдордЪрд╛рд░реА рд╕реЗ рдЕрд▓рдЧ рд╣реИ, рдЬрд┐рд╕рдХреЗ рдХрдИ-рдХрдИ рд╕рдВрдмрдВрдз рд╣реИрдВред рдЗрд╕рд▓рд┐рдП рд╣рдо рдХрдХреНрд╖рд╛рдУрдВ рдХреЗ рддрд░реНрдХ рдХреЛ рдЕрд▓рдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕реЗ рд╕рдВрдмрдВрдзреЛрдВ рдХреЗ рдПрдХ рдЕрд▓рдЧ рд╕реЗрдЯ рдХреЗ рд╕рд╛рде рднрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдиреБрд░реЛрдз рдХреЗ рдкрд░рд┐рдгрд╛рдорд╕реНрд╡рд░реВрдк, рд╣рдо рдХрд░реНрдордЪрд╛рд░рд┐рдпреЛрдВ рдореЗрдВ рд╕реЗ рдПрдХ рдХреЗ рдХреМрд╢рд▓ рдХреЛ рджреЗрдЦреЗрдВрдЧреЗред
рдЪреВрдВрдХрд┐ рдХрд░реНрдордЪрд╛рд░реА рдХрдИ рд╡рд┐рднрд╛рдЧреЛрдВ рдореЗрдВ рд╣реЛ рд╕рдХрддрд╛ рд╣реИ, рдЗрд╕рд▓рд┐рдП рдПрдХ рд╕рдВрдмрдВрдз рдмрдирд╛рдПрдВ рдЬреЛ рдЖрдкрдХреЛ рдпрд╣ рдЬрд╛рдирдХрд╛рд░реА рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рдЕрдиреБрдорддрд┐ рджреЗрддрд╛ рд╣реИред
EmployeeWithDepartments рд╡рд░реНрдЧ рдХреЛ рдХрд░реНрдордЪрд╛рд░реА рд╕реЗ рд╡рд┐рд░рд╛рд╕рдд рдореЗрдВ рдорд┐рд▓рд╛ рдФрд░ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдЬреЛрдбрд╝реЗрдВ:
class EmployeeWithDepartments(Employee): departments = relation( Department, # primaryjoin=EmployeeDepartments.employee_id == Employee.id, secondary=EmployeeDepartments.__tablename__, # secondaryjoin=EmployeeDepartments.department_id == Department.id, )
рдмрдирд╛рдпрд╛ рд╡рд░реНрдЧ рдПрдХ рдирдпрд╛ рдбреЗрдЯрд╛рдмреЗрд╕ рддрд╛рд▓рд┐рдХрд╛ рдирд╣реАрдВ рд╣реИред рдпрд╣ рдЕрднреА рднреА рдПрдХ рд╣реА рдХрд░реНрдордЪрд╛рд░реА рддрд╛рд▓рд┐рдХрд╛ рд╣реИ, рдХреЗрд╡рд▓ relation
рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╡рд┐рд╕реНрддрд╛рд░рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред рдЗрд╕ рддрд░рд╣ рдЖрдк рдкреНрд░рд╢реНрдиреЛрдВ рдореЗрдВ Employee
рдпрд╛ EmployeeWithDepartments
рд╕рд╛рд░рдгреА рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЕрдВрддрд░ рдХреЗрд╡рд▓ relation
рдХреА рдЕрдиреБрдкрд╕реНрдерд┐рддрд┐ / рдЙрдкрд╕реНрдерд┐рддрд┐ рдореЗрдВ рд╣реЛрдЧрд╛ред
рдкрд╣рд▓рд╛ рддрд░реНрдХ рдмрддрд╛рддрд╛ рд╣реИ рдХрд┐ рд╣рдо рдХрд┐рд╕ рддрд╛рд▓рд┐рдХрд╛ рд╕реЗ relation
рдмрдирд╛рдПрдВрдЧреЗред
primaryjoin
рд╡рд╣ рд╕реНрдерд┐рддрд┐ рд╣реИ рдЬрд┐рд╕рдХреЗ рджреНрд╡рд╛рд░рд╛ рдСрдмреНрдЬреЗрдХреНрдЯ рд╕реЗ рдЬреБрдбрд╝реА рд╣реЛрдиреЗ рд╕реЗ рдкрд╣рд▓реЗ рджреВрд╕рд░реА рддрд╛рд▓рд┐рдХрд╛ рдХреЛ рдЬреЛрдбрд╝рд╛ рдЬрд╛рдПрдЧрд╛ред
secondary
рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП рд╡рд┐рджреЗрд╢реА_рдХреА рдпреБрдХреНрдд рддрд╛рд▓рд┐рдХрд╛ рдХрд╛ рдирд╛рдо рд╣реИред рдХрдИ-рд╕реЗ-рдХрдИ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
secondaryjoin
- рдЕрдВрддрд┐рдо рдХреЗ рд╕рд╛рде рдордзреНрдпрд╡рд░реНрддреА рддрд╛рд▓рд┐рдХрд╛ рдХреЗ рдорд┐рд▓рд╛рди рдХреЗ рд▓рд┐рдП рд╕реНрдерд┐рддрд┐рдпрд╛рдВред
primaryjoin
рдФрд░ primaryjoin
рдЬрдЯрд┐рд▓ рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдкрддреНрд░рд╛рдЪрд╛рд░ рдХреЛ рд╕реНрдкрд╖реНрдЯ рд░реВрдк рд╕реЗ рдЗрдВрдЧрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд╛рд░реНрдп рдХрд░рддреЗ рд╣реИрдВред
рдХрднреА-рдХрднреА рдРрд╕реА рдкрд░рд┐рд╕реНрдерд┐рддрд┐рдпрд╛рдБ рдЙрддреНрдкрдиреНрди рд╣реЛрддреА рд╣реИрдВ рдЬрдм рдРрд╕реЗ рдлрд┐рд▓реНрдЯрд░реНрд╕ рдмрдирд╛рдирд╛ рдЖрд╡рд╢реНрдпрдХ рд╣реЛрддрд╛ рд╣реИ рдЬрд┐рдирдХреЗ рдХреНрд╖реЗрддреНрд░ рд╕рдВрдмрдВрдзреЛрдВ рдореЗрдВ рдШреЛрд╖рд┐рдд рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВ, рдФрд░ рд╕рдВрдмрдВрдз, рдореВрд▓ рд╡рд░реНрдЧ рдХреЗ рд╕рдВрдмрдВрдз рд╣реЛрддреЗ рд╣реИрдВред
EmployeeWithCadreMovements -> relation(CadreMovement) -> field
рдпрджрд┐ рд╕рдВрдмрдВрдз рдорд╛рдиреЛрдВ рдХреА рд╕реВрдЪреА рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд░рддрд╛ рд╣реИ, рддреЛ .any () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдП, рдпрджрд┐ рдХреЗрд╡рд▓ рдПрдХ рдореВрд▓реНрдп рдкреНрд░рджрд╛рди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ, рддреЛ .has () рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рдирд╛ рдЪрд╛рд╣рд┐рдПред
рдПрдХ рдмреЗрд╣рддрд░ рд╕рдордЭ рдХреЗ рд▓рд┐рдП, рдЗрд╕ рдирд┐рд░реНрдорд╛рдг рдХреА рд╡реНрдпрд╛рдЦреНрдпрд╛ SQL рднрд╛рд╖рд╛ рдореЗрдВ рдореМрдЬреВрдж () рдирд┐рд░реНрдорд╛рдг рдореЗрдВ рдХреА рдЬрд╛рдПрдЧреАред
рд╣рдо рдХрд╛рд░рдг рдлрд╝рдВрдХреНрд╢рди рдкреИрд░рд╛рдореАрдЯрд░ рдХреЛ рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, simple
рд╕рд╛рде рдлрд╝рдВрдХреНрд╢рди рдХрд╣рддреЗ рд╣реИрдВред
lesson6
def has_in_relations(session: DBSession, reason: str): employees = session.query(EmployeeWithCadreMovements).filter(EmployeeWithCadreMovements.cadre_movements.any(CadreMovement.reason == reason)).all() return employees output: [Steve Rogers, Tony Stark]
lession7
рдПрдХрддреНрд░реАрдХрд░рдг рдлрд╝рдВрдХреНрд╢рди рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рд╕рдВрдмрдВрдз рдкреНрд░рд╛рдкреНрдд рдХрд░рдиреЗ рдХреА рд╕рдВрднрд╛рд╡рдирд╛ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рд╣рдореЗрдВ рдХрд┐рд╕реА рд╡рд┐рд╢рд┐рд╖реНрдЯ рдЙрдкрдпреЛрдЧрдХрд░реНрддрд╛ рдХрд╛ рдЕрдВрддрд┐рдо рдХрд╛рд░реНрдорд┐рдХ рдЖрдВрджреЛрд▓рди рдорд┐рд▓рддрд╛ рд╣реИред
рдкреНрд░рд╛рдЗрдорд░реАрдЬреЛрди рдЯреЗрдмрд▓ рдореЗрдВ рд╢рд╛рдорд┐рд▓ рд╣реЛрдиреЗ рдХреЗ рд▓рд┐рдП рдПрдХ рд╢рд░реНрдд рд╣реИ (рдпрджрд┐ рдЖрд▓рд╕реА = 'рдЬреНрд╡рд╛рдЗрди рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИ')ред рдпрд╛рдж рд░рдЦреЗрдВ рдХрд┐ рдЪрдпрди рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдЙрдкрдпреЛрдЧ рдХрд┐рдпрд╛ рдЬрд╛рддрд╛ рд╣реИред
рдЗрд╕ рд╕реНрдерд┐рддрд┐ рдореЗрдВ, рдХреНрд▓рд╛рд╕ рд╡рд┐рд╢реЗрд╖рддрд╛ рдХреЛ рдПрдХреНрд╕реЗрд╕ рдХрд░рддреЗ рд╕рдордп рдПрдХ рдЕрд▓рдЧ рдЕрдиреБрд░реЛрдз рдЙрддреНрдкрдиреНрди рд╣реЛрддрд╛ рд╣реИред рдпрд╣ рдЗрд╕ рдЕрдиреБрд░реЛрдз рдХреЗ рд▓рд┐рдП рд╣реИ рдХрд┐ рд╣рдо рдлрд╝рд┐рд▓реНрдЯрд░рд┐рдВрдЧ рд╢рд░реНрддреЛрдВ рдХреЛ рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред
рдЬреИрд╕рд╛ рдХрд┐ рдЖрдк рдЬрд╛рдирддреЗ рд╣реИрдВ, рдЖрдк тАЬрд╢реБрджреНрдзтАЭ рд░реВрдк рдореЗрдВ рдПрдХрддреНрд░реАрдХрд░рдг рдХрд╛рд░реНрдпреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ WHERE рдХреА рд╕реНрдерд┐рддрд┐ рдореЗрдВ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдЗрд╕рд▓рд┐рдП рд╣рдо рд╕рдВрдмрдВрдз рдирд┐рд░реНрджрд┐рд╖реНрдЯ рдХрд░рдХреЗ рдЗрд╕ рд╕реБрд╡рд┐рдзрд╛ рдХреЛ рд▓рд╛рдЧреВ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ
рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдорд╛рдкрджрдВрдбреЛрдВ рдХреЗ рд╕рд╛рде:
last_cadre_movement = relation( CadreMovement, primaryjoin=and_( CadreMovement.employee == Employee.id, uselist=False, CadreMovement.id == select([func.max(CadreMovement.id)]).where(CadreMovement.employee == Employee.id) ) )
рдирд┐рд╖реНрдкрд╛рджрд┐рдд рд╣реЛрдиреЗ рдкрд░, рдЕрдиреБрд░реЛрдз рдЗрд╕ рддрд░рд╣ рд╕реЗ рд╕рдВрдХрд▓рд┐рдд рд╣реЛрддрд╛ рд╣реИ:
SELECT cadre_movements.id AS cadre_movements_id, cadre_movements.created_at AS cadre_movements_created_at, cadre_movements.updated_at AS cadre_movements_updated_at, cadre_movements.employee AS cadre_movements_employee, cadre_movements.old_department AS cadre_movements_old_department, cadre_movements.new_department AS cadre_movements_new_department, cadre_movements.reason AS cadre_movements_reason FROM cadre_movements WHERE cadre_movements.employee = %(param_1)s AND cadre_movements.id = ( SELECT max(cadre_movements.id) AS max_1 FROM cadre_movements WHERE cadre_movements.employee = %(param_1)s )
рдЬреАрдердм рд▓рд┐рдВрдХ
рдкрд░рд┐рдгрд╛рдо
SQLAlchemy рдПрдХ рд╢рдХреНрддрд┐рд╢рд╛рд▓реА рдХреНрд╡реЗрд░реА рдмрд┐рд▓реНрдбрд┐рдВрдЧ рдЯреВрд▓ рд╣реИ рдЬреЛ рд╡рдВрд╢рд╛рдиреБрдХреНрд░рдо рдХрд╛ рд╕рдорд░реНрдерди рдХрд░рдХреЗ рд╡рд┐рдХрд╛рд╕ рдХреЗ рд╕рдордп рдХреЛ рдХрдо рдХрд░рддрд╛ рд╣реИред
рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ ORM рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдиреЗ рдФрд░ рдЬрдЯрд┐рд▓ рдкреНрд░рд╢реНрдиреЛрдВ рдХреЛ рд▓рд┐рдЦрдиреЗ рдХреЗ рдмреАрдЪ рдПрдХ рдорд╣реАрди рд░реЗрдЦрд╛ рд░рдЦрдиреА рдЪрд╛рд╣рд┐рдПред рдХреБрдЫ рдорд╛рдорд▓реЛрдВ рдореЗрдВ, ORM рдбреЗрд╡рд▓рдкрд░ рдХреЛ рднреНрд░рдорд┐рдд рдХрд░ рд╕рдХрддрд╛ рд╣реИ рдпрд╛ рдХреЛрдб рдХреЛ рдмреЛрдЭрд┐рд▓ рдФрд░ рдЕрдкрдардиреАрдп рдмрдирд╛ рд╕рдХрддрд╛ рд╣реИред
рд╕реМрднрд╛рдЧреНрдп рд╣реИ