💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: clck.ru/3B5gwP 💡 Забирай роадмап изучения самого востребованного фреймворка на Python - FastAPI здесь: t.me/ArtemShumeikoBot
меня горит у меня прокт на запускаться с твоими путями я уже 1 в 1 все с гита скопировал и доабвлял __init__.py и удалял и делал пути auth.models ..models .models разные варинаты он ругаеться что не так ???
Для того чтобы alembic автоматически добавлял дату создания миграции в её название, достаточно раскомментировать следующую строчу в alembic.ini: file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
для тех кто использует классы , вместо Table и получает при гет запросе ошибку сериализации возвращя ответ через .all() попробуйте result.mappings().all()
также получилось устранить ошибку добавлением модели ответов в эндпоинт response_model=List[list] и подключением библиотеки from typing import List соответственно return result без .all(). C mappings лучше понравилось.
такой проникновенный взгляд после фразы - "нам нужно удалить буковку Z" xD хотелось бы посмотреть разбор от автора про flush и commit, autocommit и autoflush)
Очень классный и полезный урок! Отдельное спасибо за объяснение SQL-инъекций. Да и вообще круто, что ты останавливаешься на таких терминах и подробно разъясняешь их.
Можно писать только классы, а для работы с таблицей при async достаточно сделать user = models.User.__table__. Вот и табличка из класса модели :-) То есть все можно описать декларативным подходом, а императивный просто вызвать через __table__.
Автор, красавчик! Все дружно сидим и учимся) ПС. пересмотрел видео, автор 21: 15 сказать что "модель", скорее всего он хотел сказать отображение. Как пишут на вики: ORM по англ. - это Object-Relational Mapping. А по рус. - это объектно-реляционное отображение, или преобразование.
задумался зачем 2 таблицы users и думаю,после видео буду искать,и какое же было мое удивление что ты об этом рассказал! Редко пишу комменты, спасибо за твой труд!)
Интересный смысл использования ORM у вас - онли защита от инъекций!)) А мне казалось главный козырь ORM независимость от вида реляционной БД и легкая замена одной на другую БД (т.е. универсальность)! ORM (англ. Object-Relational Mapping, рус. объектно-реляционное отображение) - это технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования, создавая “виртуальную объектную базу данных” 1. Она позволяет взаимодействовать с базами данных, используя высокоуровневые методы языков программирования, а не SQL-запросы
Про ассинхронный Alembic, в официальной документации есть раздел Using Asyncio with Alembic. Да, Alembic напрямую не предоставляет async api, но использовав async template при выполнении команды alembic init есть возможность использовать SQLAlchemy Async engine для запуска миграций.
я уже довольно продолжительное время работаю на FastAPI и даже при разделении на сервисы нет необходимости созданий множества Metadata, лучшей практикой я считаю было бы созданием глобального metadata и к ниму привязать все таблицы. А в alembic просто импортировать ваши таблицы и глобальную metadata.
Всё супер, картинка, звук, подача материала, единственное не нравится когда вы вставляете кусок кода для ускорения процесса (у нас его нету, а брать с репозитория не охота, т.к. хочется всё по шагово вникать, так сказать строчка за строчкой, а тут в начале видео бац и вся структура проекта изменилась..... взрыв мозга))) )
Спасибо огромное за обучающий материал! очень много интересного для себя узнал! Всем. кто критикует автора, в комментах, почему бы вам не снять свои обучающие видео? в ютубе пока что это лучшие видео по fastapi на руссом языке
Отличный урок, спасибо большое. На моменте отправки ответа с данными из базы у меня падала ошибка о том, что фастапи не может сериализовать данные в JSON ([TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]) Некоторое время поисков и попыток получилось решить просто прогоном всех записей циклом через схему модельки с укакзанием полей. Криво, но работает. Надеюсь в следующих уроках решим вопрос)
Единственное, я просто создал список словарей, и в цикле в каждый словарь добавлял значения. Вы так же или как-то по-другому? Слово "через схему" насторожило
@@user-en3qo2zb8i через pydantic схему. Вообще по-хорошему делать с помощью декларативного метода модельки (классом). Тогда можно все сильно проще организовать
Добрый день. Подскажите почему на видео не было ошибки при получения get запроса(return result.all())? 29 минута. У меня была ошибка ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have dict attribute')]. Когда исправил на return result.mappings().all() ошибка пропала.
Что то я не нашел рабочего решения, гет запрос на получение из бд из таблицыс операциями ошибка :raise ValueError(errors) from e ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]
Спасибо из своего опыта скажу - db инициализацию (создание таблиц, триггеров, функций, ...) стоит выносить в отдельную папку будет меньше забот при масштабировании проекта
"...и напиши какой-нибудь хороший комментарий. Или плохой. Неважно." На самом деле, вот эта фраза во мне стриггерила крайне негативное отношение. Да, я понимаю, что, технически, без разницы, будут тебя в комментах восхвалять или мешать с гавном - это все равно будет +1 в COUNT(comments), а именно это является базой для алгоритмов Ютуба - но, все же, прям настолько людей считать мясом/биомассов/циферками - ну такое себе. Я, в целом, мог бы попытаться додумать, что ты, возможно, имел ввиду что-то типа "...напишите любой коммент, который будет выражать ваше мнение, каким бы оно ни было" - но есть вероятность, что реальность будет именно такова, как мне показалось изначально. Но это так, придирка. А плейлист зачетный - реально классно все рассказываешь.
Большое вам спасибо! Начал изучать FastAPI с 0 по вашим урокам, очень подпольные и понятные видео. Но никак не могу разобраться в структуре put запроса для обновления данных в таблицах. Не могли бы немного подсказать как бы выглядел такой запрос для обновления данных на вашем примере(для обновления данных в таблице с операциями). Буду очень благодарен.
Спасибо за курс, очень полезно. 1. Расскажите про библиотеку SQLModel от создателя FastAPI (показалась очень удобной). 2. Не могу понять как, при использовании декларативного метода описания таблиц, делать миграции через алембик? Где брать метадату?
1. Изучу, спасибо за предложение 2. При декларативном стиле объявляется переменная Base = declarative_base(), от которой наследуется наши модели. В файл env.py импортируется переменная Base (аккумулирующая в себе данные о созданных моделях) и в target_metadata передаётся Base.metadata Больше информации тут: docs.sqlalchemy.org/en/13/orm/extensions/declarative/basic_use.html
Сейчас в sqlalchemy что-то изменили, и теперь нельзя получить список словарей (объектов), написав result.all() (возвращается объект типа Sequence[Row[_TP]]). По этой теме даже появился вопрос на Стаковерфлоу, посвященный именно этому моменту именно из этого видео. Вместо result.all() теперь работает что-то вроде [dict(r._mapping) for r in result]. Надеюсь, с более сложной структурой это также будет работать. P.s. увидел в комментариях более элегантное решение через result.mappings().all()
За контент спасибо, что занимаетесь просветительской деятельностью! А вот теперь ложка дёгтя: Может быть из-за опыта в корпоративной разработки (более 15 лет) и на другом языке (С++/C#), но назвать папку со всем что относится к сервису сваленную в одну кучу best practices это конечно очень по питонячи. И да понятно почему такой подход, что бы не заворачиваться с импортами, но эта "архитектура" файловой структуры ИМХО не есть лучшие практика даже с 2К звёзд. И Вот один из кейсов которые могут возникнуть возьмём exceptions понятное дело что у auth, aws, etc... они зачастую свои, но есть и общие которые лежат в корне src подход в принципе на 3- потому что exceptions это многогранное название файла говорящие о его содержании ровно ничего кроме того что "Уважаемый читатель кода, будьте так добры откройте меня и я вам покажу все прекрасные исключения которые в меня поместил мой создатель, что бы создатель смог отлавливать нештатные ситуации в своём коде". Да я понимаю что это так по питонячи набросать всё в один файл, а дальше тащить всё из него не заворачиваясь над импортами, но и читать этот код становится труднее так как приходятся открывать файлы для того что бы посмотреть что за код в этом файле, а не брать в расчёт нейминг файла. Как делаю это я и даже на Python выношу все exception в отдельные группы с разбивкой по файлам, где в именах файлов какие действия обрабатывают exceptions, да приходятся ручками слегка шаманить в __init__.py прописывая импорты, но при взгляде на структуру, как опять мне кажется я чётко представляю из названия файла, какие внутри него возможности, будь exception, model, etc... Может я из старой школы но даже в нейминге фабрик я дописываю factory и делаю это на автомате. Ну если рассмотреть данную практику не с точки зрения PET проекта, а с точки зрения DDD то новому члену команды приходится шерстить однотипные файлы что бы построить в голове что где лежит, для бизнеса это трата средств на сотрудника который делает ровно ничего, а просто изучает структуру проекта, что бы не дай бог не написать новый exception в очередном файле exceptions.py который будет на 99% похож на тот что был в файле exceptions.py, но на уровне выше. Всё то же самое и с моделями, а если ещё принять, что модели бизнес логике это совсем немного не сущности DB слоя и для трансфера между слоями нужны DTO, то эта "лучшая практика" превращается в свалку всего и вся. Но как говорится это питонячий путь.
Спасибо за ваш развернутый комментарий! Я частично согласен с тезисами, если речь идет о проекте среднего или большого размера (какими зачастую являются коммерческие проекты), хоть и встречаю примеры использования подобной в видео структуры в крупных open-source проектах.
Есть куча проэктов на Django где люди вообще не слышали что такое сервисы и толкают их в views или models. Эти проэкты годыми работают на продакшине . Python язык для новичков, которые не хотят строить абстракции над абстракциями , не хотят ломать голову о чистой архитектуре. Я понимаю что програмисты C# строят патtерн Репозиторий над EntityFremework, хотя он там внутри дай только усложнить. На деле бизнес ценит скорость разработки . Если в пайтоне будут расказывать сразу про правильную архитектуру , он совсем не покажиться легким. Не стоит усложнять простое с опытом все придёт.
@@BestDron , Бизнес ценит скорость только на этапе старта, что бы иметь выгодные конкурентные позиции, далее бизнесу важна стабильность (у нас в проекте планы фичей до Q4 2023 расписаны) так как нестабильность приносит финансовые затраты бизнесу и это ему не нравится. Да не буду спорить что на старте как язык прототипирования и пробы идеи с питонякой поспорить ну оооочень сложно, но на дистанции при условии того что идея выстрелила питоняка уступает место другим языкам и это логично в следствии своих скоростных характеристик. В тырпрайзных решениях Вы довольно редко увидите python как core яп, в основном там C#/Java/Rust (с недавнего времени) и это не связанно с тоннами легаси которые присущи любому крупному проекту (из жизни в проекте над котором я работаю (финтех) есть библиотека с датой компиляции 1998 год написана на С и она в боевом проекте уже 25 лет, и да в планах на Q3 актуализировать её на C#). Но говорить что python не используется в крупных проектах это обманывать самого себя, он используется но его место это больше решение сопутствующих проблем когда нужно вот прям тут и быстро. Сколько раз было когда требовалось решение прикладной задачи и я выбирал Python против С#/Rust и мне было не особо интересно что код будет медленнее делать работу, главное что я потрачу меньше времени для самого решения этой задачи. Я намерено не затрагиваю js и его ипостаси для бэка потому что имею личную неприязнь к этому яп. Хотя в одном не большом холиварчики нода уделала по скорости гошечку. По поводу чистоты архитектуры, ну честно это не про разработчиков на python (привет Protocol и Generic). Если с самого начала не объяснять разработчикам основы чистой архитектуры то даже с опытом это не придёт, потому что сила привычки возьмет в верх. Выше пример с 2К звездочками и свалкой явный показатель. Вы часто видели проекты на python следующие принципам SOLID ? Вот попробуйте сейчас коллегам/друзьям/знакомым которые пишут на python начать рассказывать про IoC/DI да на Вас будут смотреть с квадратными глазами, а потому что они привыкли нужна зависимость импорт->инстанцирование погнали использовать и такое размазано по всем файлам это уже привычка у них. или полезут искать в pip библиотеку DI контейнерезации, а то что есть Pure DI и для его реализации не нужны сторонние библиотеки они не задумываются потому что это опять дело привычки. Аналогично дело обстоит с подходом программированием от интерфейсов, да потому что лень это же надо продумать, а тут х..як и уже в проде. Да на python можно писать сложные продуманные архитектурные решения, но в виду его низкого порога вхождения (привет бота писателям на aiogram) этим обычно пренебрегают в угоду быстроты разработки и быстрой выкотки готового решения в прод. Но в крупных решениях для бизнеса Вы как разработчик всего лишь винтик в большом механизме и механизм не должен тормозить и ни дай бог остановится если Вас извлечь из механизма. И вот тут уже совершено другие методологии разработки, так как чем меньше новый винтик потратит времени на изучение проекта тем лучше для бизнеса и тем меньше нагрузка на других членов команды пока этот винтик притрётся и заменит предыдущего своего коллегу. Ну зачем же так про нам (разработчики на С#) лишь бы усложнять, Entity Framework это концептуально та же ORM что SQLAlchemy, да в python отличается подход работы с коллекциями и с ORM в .NET этот подход один LINQ и да python разработчику столкнувшимся с ORM в первый раз довольно непонятно как так через "." писать что то похоже на SQL но не SQL. В .Net с этим меньше проблем потому что с коллекциями Вы используете LINQ, что с ORM вы опять используете LINQ. И где же тут усложнение ?
@@artemshumeiko , M в ORM это Mapping, Мне понравилось что объяснением Вы рассказали что это представление данных, а в комментариях по коду M это не какая то абстрактная сущность на которую применяется действие и бла бла бла, а сразу к делу М на выходе модель и точка.
@@unix3d ORM Entity Framework и sqlalchemy небо и земля. Я писал о том, что EntityFramework из коробки реализует репозиторий и Unit of Work об этом пишут его разработчики. Но c# программисты делают его всё равно. EntityFramework может вызывать функции sql из кода на c# сравнивать две эти ORM не благодарно. C# отличный язык с огромной кучей синтаксического сахара, там одну задачу можно решить 50 разными способами, что пугает новичков. У меня есть коллега разработчик на c#, он говорит когда они ввели метода интерфейсов реализующие по умолчанию их мир на c# пошатнулся. Для них в голове интерфейс был абстракцией . Теперь каждый junior пытается пропехнуть эту в проду. Так нормальный мы холивар развели в комментариях по языку c# под видео на питоне.))
когда из базой данных получили данные и вернули в интерфейсе через return result.all() вот такая ошибка raise ValueError(errors) from e ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')] то есть не принимает dict
после реструктуризации проекта у Артёма на гитхабе и в видео импорт происходит так: from operations.models import operation у меня только с указанием каталога src: from src.operations.models import operation если убрать префикс src, то возникает ошибка: ModuleNotFoundError: No module named 'operations' вставка файла __itit__.py ничего не изменила. может быть, это не слишком принципиально, но хотелось бы понимать, почему у Артёма код работает
@@44animexxx79 скачал (кстати, можно клонировать только весь проект, одна папка не скачивается), открываю любой файл, относительные пути не работают. нужно делать абсолютные. возможно, потому что я работаю под Win10? у автора вроде бы Linux
Такая же беда. Я в файл __init__.py добавил следующий код: import os import sys sys.path.append(os.path.join(sys.path[0], 'src')) А приложение запускаю теперь через: uvicorn src.main:app --reload Но почему у Артема работает и без этого, а у меня нет, я так и не понял)
Я тоже обратил внимание, что возникают проблемы при вставке Z в определенное время и лучше ее стирать. Разумеется в конце этого времени как описывает пример swagger.
спасибо за уроки, у меня вопрос : я не могу найти в коде место, где мы пускаем только авторизованных пользователей на путь "/operations" - помогите найти и разобраться
Артём, извините что по имени, ещё таких два вопроса. 1. Будет ли рассказано про gunicorn поверх uvicorn (читал, что так делают, но так и не понял зачем) 2. Может было бы проще создавать подключение к БД через роутер on_event("startup") и закрытие через on_event("shutdown"). У кого-то видел в коде так было реализовано подключение... Заранее спасибо за ответы!
Спасибо за вопросы! 1. Для проекта с небольшим количеством пользователей и низким rps можно оставить только uvicorn. Если проект среднего размера и находится на одном сервере, Gunicorn + Uvicorn могут работать в связке, задействуя больше CPU, но обеспечивая больший rps. Если используется кубернетес, можно оставить uvicorn на каждом сервере. Больше информации тут: fastapi.tiangolo.com/deployment/docker/#single-container и тут: stackoverflow.com/a/71546833/18406890 2. Скорее всего тут вы правы. Упомяну об этом в следующих видео
интересно почему сразу дату в миграции alembic не добавляет, в том же Laravel для каждой миграции дата и время ставится по умолчанию... Хотя там вероятно миграции немного по другому устроены, но всё же... В django миграции тоже нумеруются, если не ошибаюсь.
Спасибо за идею! На степике в ближайшее время не планируется. Чтобы создать качественный курс, нужно довольно много времени и сил, чем я пока не располагаю.
Чтоб избежать sql - инъекций в сырых запросах_забудьте про f-string. Для этого есть свой синтаксис. Например asyncgp передает данные через $1, $2 и тд query = """SELECT some FROM some_table WHERE some = $1"""
Ребят, я не уверен, но не лучше будет использовать структуру Operation = OperationOrm(**new_operation.dict()) session.add_all(Operation ) await session.commit() Урок год назад вышел, я пока не врубаю из-за отсутствия опыта что лучше делать таким образом или использовать операции select, insert и тд из алхимии.
@@ynerush Ответ в комментариях под этим видео - ua-cam.com/video/qvzQWBEBHYw/v-deo.html Если коротко, то автор использует надстройку над синтаксисом.Без нее scalars обязателен.
Может глупый вопрос, может уже многое поменялось. Но при выполнении query = select(operation).where(operation.c.type == operation_type) result = await session.execute(query), result.all() возвращает массив кортежей, что влечёт ошибку с при передаче в return. Может кто нибудь пояснить по этому поводу? Что изменилось или я что то не так делаю?
Привет! Скажи, пожалуйста, а ты пробовал вместо Алхимии использовать Pony ORM? Мне кажется, с их веб-интерфейсом проектировки БД - очень удобный инструмент
Добрый день, кто знает, как сделать валидацию существования внешнего ключа в БД через Pydantic? Чтоб если передаем Id внешнего ключа, которого нет в бд, не возвращала 500 ошибку.
Привет, объясните, пожалуйста, зачем автор создаёт в src/auth/models.py сначала таблицу user, а потом ниже класс User, с точно такими же полями. Как я понимаю, класс юзер идёт в ОРМ алхимии, но зачем тогда нужна таблица? Она, если я не ошибаюсь, никуда не импортируется и не используется вовсе.
Автор, Я не претендую ни на какие титулы в программирование, и не являюсь программистом вовсе, смотрю подобные видео для саморазвития, и так, написать какую-нибудь штуку и посмотреть - заработает или нет. Я в упор не понимаю для чего эти миграции. Почему нельзя в базе данных (MySQL, SQLite, Postgress - админке) напрямую не задать нужные таблицы и связи ? ведь работы прописывая их в "миграциях" и в интерфейсе программы администрирования БД столько же. Вот никогда не понимал этого прикола
Когда разрабатываешь бэкенд и бд в одиночку, пожалуй, миграции будут лишним грузом. Но когда бэкендеров больше, чем 2 (пускай один разрабатывает бэкенд и бд, а остальной(ые) только бэкенд), то резко увеличивается количество времени, затрачиваемое на обмен информацией об обновлении таблиц в базе данных. Таким образом, конструируя базу данных прямо на бэкенде, разработчики могут в любой момент увидеть текущее состояние бд, а также все предыдущие, не залезая в саму базу и не мучая администратора бд своими вопросами :) Помимо этого, часто коммерческие продукты имеют версии (1.0, 2.0 и и т.д.), которые удобно поддерживать через миграции
💡 Попробуй онлайн-тренажёр для подготовки к техническому собеседованию: clck.ru/3B5gwP 💡
Забирай роадмап изучения самого востребованного фреймворка на Python - FastAPI здесь: t.me/ArtemShumeikoBot
pytest и mock хочу на реальном проекте и подробно
ПРоверка итогового проекта на безопасность и взлом
Хотелось бы увидеть реализацию функций с аутентификацией и авторизацией. Как это выглядит в коде. Должен куда-то передаваться залогиненный юзер?
меня горит у меня прокт на запускаться с твоими путями я уже 1 в 1 все с гита скопировал и доабвлял __init__.py и удалял и делал пути auth.models ..models .models разные варинаты он ругаеться что не так ???
я конечно сильно хейтить не хочу но походу курс надо перезаписать начиная с jwt и этого у меня тупо ниче не работает это пздц
"Я уже изменил файловую структуру, потому что долго было бы делать ее вместе с вами" - напомнило классическое видео "Every programming tutorial"
ахахах именно так :)
О даа именно из-за этого мне этот урок дался не легко
Да, это прям оттолкнуло. Не сделал с нами, так ещё и не показал полное содержимое файлов - сами догадывайтесь что куда пихать. Брух
@@user-gm8gh2gp2v я нашел гитхаб в описании к видео
@@user-gm8gh2gp2v изменил файловую за 5 минут. ничего сложного. единственное import надо дописывать src) но поиск по файлам выручает.
Для того чтобы alembic автоматически добавлял дату создания миграции в её название, достаточно раскомментировать следующую строчу в alembic.ini:
file_template = %%(year)d_%%(month).2d_%%(day).2d_%%(hour).2d%%(minute).2d-%%(rev)s_%%(slug)s
и почему я не посмотрел ранее бл... нагородил такое --head (Get-Date).ToString('yyyy-MM-dd')
для тех кто использует классы , вместо Table и получает при гет запросе ошибку сериализации возвращя ответ через .all()
попробуйте result.mappings().all()
также получилось устранить ошибку добавлением модели ответов в эндпоинт response_model=List[list] и подключением библиотеки from typing import List соответственно return result без .all(). C mappings лучше понравилось.
Дай бог тебе здоровья друг, целый час думал в чем загвоздка
спасибо , оч много времени сэкономил)
Спасибо) Очень выручил
Вернуть результат помогло. А вот как написан фильтр в where?
"Мы огорчены, расстроены, но не сломлены" 😀
Коротко о том, как мотивировать себя когда нужно дебажить код 😀😀
такой проникновенный взгляд после фразы - "нам нужно удалить буковку Z" xD
хотелось бы посмотреть разбор от автора про flush и commit, autocommit и autoflush)
Очень классный и полезный урок! Отдельное спасибо за объяснение SQL-инъекций. Да и вообще круто, что ты останавливаешься на таких терминах и подробно разъясняешь их.
орнул с буковки зет) молодец
Можно писать только классы, а для работы с таблицей при async достаточно сделать user = models.User.__table__. Вот и табличка из класса модели :-) То есть все можно описать декларативным подходом, а императивный просто вызвать через __table__.
Автор, красавчик!
Все дружно сидим и учимся)
ПС. пересмотрел видео, автор 21: 15 сказать что "модель", скорее всего он хотел сказать отображение.
Как пишут на вики:
ORM по англ. - это Object-Relational Mapping.
А по рус. - это объектно-реляционное отображение, или преобразование.
Было бы неплохо прикрепить где-то запрос на вставку дефолтных данных в таблицу operation
insert into operations values
(1, 124, 'H23D8K45M1', 'bond', '2023-10-25 15:30:45', 'выплата купонов'),
(2, 376, 'C8H6A4N0C7', 'currency', '2023-10-25 14:27:12', 'покупка валюты'),
(3, 899, 'B0O2N1D1', 'bond', '2023-10-25 13:12:54', 'покупка купонов'),
(4, 543, 'C1U8R3R3E2N9C2Y', 'currency', '2023-10-25 12:45:01', 'покупка валюты'),
(5, 198, 'K3D8S0L6F2J5S2', 'currency', '2023-10-25 11:31:23', 'продажа валюты'),
(6, 617, 'R1B4M1B5I7X', 'bond', '2023-10-25 10:14:27', 'продажа валюты'),
(7, 445, 'A4O5W7E2Y7F2H3D', 'currency', '2023-10-25 09:09:11', 'покупка купонов'),
(8, 753, 'E8K5V7I2K9A8L5', 'bond', '2023-10-25 08:02:16', 'покупка купонов'),
(9, 623, 'T9B0O5O7N3D', 'bond', '2023-10-25 07:01:00', 'продажа валюты'),
(10, 124, 'P0U3R1C1H5A3S1E', 'bond', '2023-10-25 06:20:51', 'покупка купонов'),
(11, 376, 'G7H3J9S0V5F9L4', 'currency', '2023-10-25 05:01:47', 'продажа валюты'),
(12, 899, 'B4Y8Y4H4H7A1N2A', 'bond', '2023-10-25 04:14:22', 'покупка купонов'),
(13, 543, 'V4A1L5U7T2Y', 'currency', '2023-10-25 03:40:36', 'выплата купонов'),
(14, 198, 'L4A7T1Y2S8D9V9X1', 'currency', '2023-10-25 02:12:04', 'покупка валюты'),
(15, 617, '7H3J98Y4H41Y', 'bond','2023-10-25 06:20:51','выплата купонов'),
(16, 445, 'J9S0V3J98R1B4', 'currency', '2023-10-25 05:01:47','покупка валюты'),
(17, 753, '1U8R3R3E5O74A', 'bond', '2023-10-25 04:14:22', 'покупка купонов'),
(18, 623, '0L6FL5U7J9', 'bond', '2023-10-25 03:40:36', 'покупка валюты'),
(19, 408, 'O7N3J98YU8R3', 'bond', '2023-10-25 02:12:04', 'продажа валюты'),
(20, 795, '6A4NH230L', 'bond', '2023-10-25 06:20:51', 'продажа валюты');
задумался зачем 2 таблицы users и думаю,после видео буду искать,и какое же было мое удивление что ты об этом рассказал! Редко пишу комменты, спасибо за твой труд!)
Интересный смысл использования ORM у вас - онли защита от инъекций!)) А мне казалось главный козырь ORM независимость от вида реляционной БД и легкая замена одной на другую БД (т.е. универсальность)!
ORM (англ. Object-Relational Mapping, рус. объектно-реляционное отображение) - это технология программирования, которая связывает базы данных с концепциями объектно-ориентированных языков программирования, создавая “виртуальную объектную базу данных” 1. Она позволяет взаимодействовать с базами данных, используя высокоуровневые методы языков программирования, а не SQL-запросы
ORM это слой между твои кодом и бд в свою очередь между бд и orm есть слой ядра Алхимии погугли видосы про нее. Ну и про паттерн Repository.
ну все же ORM это преобразование данных из таблиц в объекты со всеми связями, а все остально - это уже фичи.
ORM - Object-Relational model ? . автор senoir или еще middle ? я даже еще не джун
Спасибо большое, стало намного яснее. С наступившим новым годом.
И да с часовыми поясами надо аккуратнее, а то может быть ошибка))
Артём, спасибо большое за твои уроки. Отличная подача материала, хорошая картинка, звук. Продолжай в том же духе!
Спасибо! Впереди ещё много интересных уроков ;)
Про ассинхронный Alembic, в официальной документации есть раздел Using Asyncio with Alembic. Да, Alembic напрямую не предоставляет async api, но использовав async template при выполнении команды alembic init есть возможность использовать SQLAlchemy Async engine для запуска миграций.
я уже довольно продолжительное время работаю на FastAPI и даже при разделении на сервисы нет необходимости созданий множества Metadata, лучшей практикой я считаю было бы созданием глобального metadata и к ниму привязать все таблицы. А в alembic просто импортировать ваши таблицы и глобальную metadata.
Действительно, хороший вариант! Спасибо
Очень годно)
Я в х2, с перемоточками, смотрю и закрываю пробелы)
Это лучший канал по FastApi, у меня все)
Спасибо за поддержку!
Хотелось бы увидеть видео про тесты с sqlalchemy orm с подвязкой тестового бд
Артем, большое спасибо за твой труд!
Здравствуйте, очень хорошо и понятно объясняете. Спасибо Вам.
Всё супер, картинка, звук, подача материала, единственное не нравится когда вы вставляете кусок кода для ускорения процесса (у нас его нету, а брать с репозитория не охота, т.к. хочется всё по шагово вникать, так сказать строчка за строчкой, а тут в начале видео бац и вся структура проекта изменилась..... взрыв мозга))) )
Учту, спасибо
Просто лучший! Спасибо огромное за курс
Спасибо огромное за обучающий материал! очень много интересного для себя узнал! Всем. кто критикует автора, в комментах, почему бы вам не снять свои обучающие видео? в ютубе пока что это лучшие видео по fastapi на руссом языке
Спасибо!
Спасибо большое за качественный контент! понятно, приятно смотреть и слушать! Артем, ты -лучший!
Отличный урок, спасибо большое. На моменте отправки ответа с данными из базы у меня падала ошибка о том, что фастапи не может сериализовать данные в JSON ([TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')])
Некоторое время поисков и попыток получилось решить просто прогоном всех записей циклом через схему модельки с укакзанием полей. Криво, но работает. Надеюсь в следующих уроках решим вопрос)
Та же проблема, никак не мог понять в чем дело
То же самое, через цикл сделал, но осталось чувство, что это можно решить как-то по-другому.
Единственное, я просто создал список словарей, и в цикле в каждый словарь добавлял значения. Вы так же или как-то по-другому? Слово "через схему" насторожило
@@user-en3qo2zb8i через pydantic схему. Вообще по-хорошему делать с помощью декларативного метода модельки (классом). Тогда можно все сильно проще организовать
@Vladislav Erekeshov ты лучший, спасибо большое.
Дату в модель тоже добавил строкой "date: datetime.datetime"
Подписался. Поставил лайк. Из чего-то хорошего... скажу что у ВАС имеется преподавательский талант :)
круто, спасибо!
ORM - Object-Relational Mapping
Большое спасибо за урок, он был очень познавательным!
Спасибо за ваш труд!
:D ахах это лицо после иправления даты, харош!!!11
Спасибо. Хорошая работа. Продолжайте делать обучающие видео, у вас отлично получается.
Большое спасибо!
про организацию файловой системы отдельное спасибо
Пишу какой-то хороший комментарий: твои обучалки великолепны! Спасибо!
Лайк за картинку и звук
Отлично! Спасибо за уроки!
Артем спасибо за такие классные видео. Ты большой молодец.)
почему-то алхимия выдала кортежи а не json/dict как на видео, помогла типизация
class OperationModel(BaseModel):
id: int
quantity: str
figi: str
instrument_type: str
date: datetime.datetime
type: str
@router.get('/{operation_type}', response_model=List[OperationModel])
async def get_specific_operation(operation_type:str , session: AsyncSession = Depends(get_async_session)):
query = select(operation).where(operation.c.type == operation_type)
result = await session.execute(query)
res = result.all()
return res
Про букву Z было смешно ))) Классный урок, спасибо !
Спасибо за урок!
Здесь во избежание проблем нужно удалить буковку Z. *взгляд в камеру*
Добрый день. Подскажите почему на видео не было ошибки при получения get запроса(return result.all())? 29 минута. У меня была ошибка ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have dict attribute')]. Когда исправил на return result.mappings().all() ошибка пропала.
старая версия алхимии в видео
Спасибо за урок) А можете в будущем сделать пример с микросервисной архитектурой на FastAPI(с парой сервисов) ?
Пожалуйста! :) Скорее всего будет дополнительный сервис для рассылок по почте
Спасибо за видео, все очень доступно и понятно!
Спасибо :)
спасибо брат за уроки
Артём, вы делаете богоугодное дело! Спасибо большое за проделанную работу.
Это самый "плохой" комментарий! Спасибо за это видео и плейлист в целом! ))))
спасибо!
Артем спасибо за видео! И запрос на заполнение INSERT INTO public.operation
VALUES (3, 1,'TCGA', 'bond', '2022-11-21 12:44:00', 'Выплата купононов'),(2, 10,'TCGM', 'bond', '2012-10-21 12:44:00', 'Покупка ценных бумаг');
спасибо хоть на этом, автор благополучно забить на это решил
Что то я не нашел рабочего решения, гет запрос на получение из бд из таблицыс операциями ошибка :raise ValueError(errors) from e
ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]
Попробуй вместо result.all() использовать result.scalars().all()
@@kayriat-youtube39 тогда будет выводится только id у всех результатов.
Тоже встрял на этом, пока решения не нашел(
Кто-нибудь нашел решение данной проблемы?
@@artem_raudsep return [dict(r._mapping) for r in result]
хороший контент по FastAPI !
Спасибо :) Впереди еще много контента
Спасибо
из своего опыта скажу - db инициализацию (создание таблиц, триггеров, функций, ...) стоит выносить в отдельную папку
будет меньше забот при масштабировании проекта
Спасибо за видео.
Ну плохой комментарий, так плохой комментарий😂, а так классная серия видосов, спасибо большое)
Зачем нужны pydentic models - если коротко?
огромное спасибо =)
"...и напиши какой-нибудь хороший комментарий. Или плохой. Неважно."
На самом деле, вот эта фраза во мне стриггерила крайне негативное отношение.
Да, я понимаю, что, технически, без разницы, будут тебя в комментах восхвалять или мешать с гавном - это все равно будет +1 в COUNT(comments), а именно это является базой для алгоритмов Ютуба - но, все же, прям настолько людей считать мясом/биомассов/циферками - ну такое себе.
Я, в целом, мог бы попытаться додумать, что ты, возможно, имел ввиду что-то типа "...напишите любой коммент, который будет выражать ваше мнение, каким бы оно ни было" - но есть вероятность, что реальность будет именно такова, как мне показалось изначально.
Но это так, придирка.
А плейлист зачетный - реально классно все рассказываешь.
годный контент 👍
28:47 Артëм, ты откуда взял данные для этой таблицы? Дай ссылку.
36:56, хорошая отсылка, ахахахаха
Для хранения float используется Decimal.
Большое вам спасибо! Начал изучать FastAPI с 0 по вашим урокам, очень подпольные и понятные видео. Но никак не могу разобраться в структуре put запроса для обновления данных в таблицах. Не могли бы немного подсказать как бы выглядел такой запрос для обновления данных на вашем примере(для обновления данных в таблице с операциями). Буду очень благодарен.
Спасибо за курс, очень полезно.
1. Расскажите про библиотеку SQLModel от создателя FastAPI (показалась очень удобной).
2. Не могу понять как, при использовании декларативного метода описания таблиц, делать миграции через алембик? Где брать метадату?
1. Изучу, спасибо за предложение
2. При декларативном стиле объявляется переменная Base = declarative_base(), от которой наследуется наши модели. В файл env.py импортируется переменная Base (аккумулирующая в себе данные о созданных моделях) и в target_metadata передаётся Base.metadata
Больше информации тут: docs.sqlalchemy.org/en/13/orm/extensions/declarative/basic_use.html
Легенда...
36:55 хах, неоднозначно получилось)
Где можно найти скрипт добавления данных в бд? В репе нет файла.
не решил проблему брутфорсом?))Буду благодарен если сможешь поделиться
Спасибо бро !
36:55🤣 в этот момент они могут только появиться
Сейчас в sqlalchemy что-то изменили, и теперь нельзя получить список словарей (объектов), написав result.all() (возвращается объект типа Sequence[Row[_TP]]). По этой теме даже появился вопрос на Стаковерфлоу, посвященный именно этому моменту именно из этого видео. Вместо result.all() теперь работает что-то вроде [dict(r._mapping) for r in result]. Надеюсь, с более сложной структурой это также будет работать.
P.s. увидел в комментариях более элегантное решение через result.mappings().all()
урок про файловую структуру - "я изменил файловую структуру без вас потому что с вами было бы долго"
За контент спасибо, что занимаетесь просветительской деятельностью!
А вот теперь ложка дёгтя:
Может быть из-за опыта в корпоративной разработки (более 15 лет) и на другом языке (С++/C#), но назвать папку со всем что относится к сервису сваленную в одну кучу best practices это конечно очень по питонячи. И да понятно почему такой подход, что бы не заворачиваться с импортами, но эта "архитектура" файловой структуры ИМХО не есть лучшие практика даже с 2К звёзд. И Вот один из кейсов которые могут возникнуть возьмём exceptions понятное дело что у auth, aws, etc... они зачастую свои, но есть и общие которые лежат в корне src подход в принципе на 3- потому что exceptions это многогранное название файла говорящие о его содержании ровно ничего кроме того что "Уважаемый читатель кода, будьте так добры откройте меня и я вам покажу все прекрасные исключения которые в меня поместил мой создатель, что бы создатель смог отлавливать нештатные ситуации в своём коде". Да я понимаю что это так по питонячи набросать всё в один файл, а дальше тащить всё из него не заворачиваясь над импортами, но и читать этот код становится труднее так как приходятся открывать файлы для того что бы посмотреть что за код в этом файле, а не брать в расчёт нейминг файла. Как делаю это я и даже на Python выношу все exception в отдельные группы с разбивкой по файлам, где в именах файлов какие действия обрабатывают exceptions, да приходятся ручками слегка шаманить в __init__.py прописывая импорты, но при взгляде на структуру, как опять мне кажется я чётко представляю из названия файла, какие внутри него возможности, будь exception, model, etc... Может я из старой школы но даже в нейминге фабрик я дописываю factory и делаю это на автомате.
Ну если рассмотреть данную практику не с точки зрения PET проекта, а с точки зрения DDD то новому члену команды приходится шерстить однотипные файлы что бы построить в голове что где лежит, для бизнеса это трата средств на сотрудника который делает ровно ничего, а просто изучает структуру проекта, что бы не дай бог не написать новый exception в очередном файле exceptions.py который будет на 99% похож на тот что был в файле exceptions.py, но на уровне выше. Всё то же самое и с моделями, а если ещё принять, что модели бизнес логике это совсем немного не сущности DB слоя и для трансфера между слоями нужны DTO, то эта "лучшая практика" превращается в свалку всего и вся. Но как говорится это питонячий путь.
Спасибо за ваш развернутый комментарий!
Я частично согласен с тезисами, если речь идет о проекте среднего или большого размера (какими зачастую являются коммерческие проекты), хоть и встречаю примеры использования подобной в видео структуры в крупных open-source проектах.
Есть куча проэктов на Django где люди вообще не слышали что такое сервисы и толкают их в views или models.
Эти проэкты годыми работают на продакшине .
Python язык для новичков, которые не хотят строить абстракции над абстракциями , не хотят ломать голову о чистой архитектуре.
Я понимаю что програмисты C# строят патtерн Репозиторий над EntityFremework, хотя он там внутри дай только усложнить.
На деле бизнес ценит скорость разработки . Если в пайтоне будут расказывать сразу про правильную архитектуру , он совсем не покажиться легким. Не стоит усложнять простое с опытом все придёт.
@@BestDron , Бизнес ценит скорость только на этапе старта, что бы иметь выгодные конкурентные позиции, далее бизнесу важна стабильность (у нас в проекте планы фичей до Q4 2023 расписаны) так как нестабильность приносит финансовые затраты бизнесу и это ему не нравится. Да не буду спорить что на старте как язык прототипирования и пробы идеи с питонякой поспорить ну оооочень сложно, но на дистанции при условии того что идея выстрелила питоняка уступает место другим языкам и это логично в следствии своих скоростных характеристик. В тырпрайзных решениях Вы довольно редко увидите python как core яп, в основном там C#/Java/Rust (с недавнего времени) и это не связанно с тоннами легаси которые присущи любому крупному проекту (из жизни в проекте над котором я работаю (финтех) есть библиотека с датой компиляции 1998 год написана на С и она в боевом проекте уже 25 лет, и да в планах на Q3 актуализировать её на C#). Но говорить что python не используется в крупных проектах это обманывать самого себя, он используется но его место это больше решение сопутствующих проблем когда нужно вот прям тут и быстро. Сколько раз было когда требовалось решение прикладной задачи и я выбирал Python против С#/Rust и мне было не особо интересно что код будет медленнее делать работу, главное что я потрачу меньше времени для самого решения этой задачи. Я намерено не затрагиваю js и его ипостаси для бэка потому что имею личную неприязнь к этому яп. Хотя в одном не большом холиварчики нода уделала по скорости гошечку.
По поводу чистоты архитектуры, ну честно это не про разработчиков на python (привет Protocol и Generic). Если с самого начала не объяснять разработчикам основы чистой архитектуры то даже с опытом это не придёт, потому что сила привычки возьмет в верх. Выше пример с 2К звездочками и свалкой явный показатель. Вы часто видели проекты на python следующие принципам SOLID ? Вот попробуйте сейчас коллегам/друзьям/знакомым которые пишут на python начать рассказывать про IoC/DI да на Вас будут смотреть с квадратными глазами, а потому что они привыкли нужна зависимость импорт->инстанцирование погнали использовать и такое размазано по всем файлам это уже привычка у них. или полезут искать в pip библиотеку DI контейнерезации, а то что есть Pure DI и для его реализации не нужны сторонние библиотеки они не задумываются потому что это опять дело привычки. Аналогично дело обстоит с подходом программированием от интерфейсов, да потому что лень это же надо продумать, а тут х..як и уже в проде.
Да на python можно писать сложные продуманные архитектурные решения, но в виду его низкого порога вхождения (привет бота писателям на aiogram) этим обычно пренебрегают в угоду быстроты разработки и быстрой выкотки готового решения в прод. Но в крупных решениях для бизнеса Вы как разработчик всего лишь винтик в большом механизме и механизм не должен тормозить и ни дай бог остановится если Вас извлечь из механизма. И вот тут уже совершено другие методологии разработки, так как чем меньше новый винтик потратит времени на изучение проекта тем лучше для бизнеса и тем меньше нагрузка на других членов команды пока этот винтик притрётся и заменит предыдущего своего коллегу.
Ну зачем же так про нам (разработчики на С#) лишь бы усложнять, Entity Framework это концептуально та же ORM что SQLAlchemy, да в python отличается подход работы с коллекциями и с ORM в .NET этот подход один LINQ и да python разработчику столкнувшимся с ORM в первый раз довольно непонятно как так через "." писать что то похоже на SQL но не SQL. В .Net с этим меньше проблем потому что с коллекциями Вы используете LINQ, что с ORM вы опять используете LINQ. И где же тут усложнение ?
@@artemshumeiko , M в ORM это Mapping, Мне понравилось что объяснением Вы рассказали что это представление данных, а в комментариях по коду M это не какая то абстрактная сущность на которую применяется действие и бла бла бла, а сразу к делу М на выходе модель и точка.
@@unix3d ORM Entity Framework и sqlalchemy небо и земля. Я писал о том, что EntityFramework из коробки реализует репозиторий и Unit of Work об этом пишут его разработчики. Но c# программисты делают его всё равно.
EntityFramework может вызывать функции sql из кода на c# сравнивать две эти ORM не благодарно. C# отличный язык с огромной кучей синтаксического сахара, там одну задачу можно решить 50 разными способами, что пугает новичков. У меня есть коллега разработчик на c#, он говорит когда они ввели метода интерфейсов реализующие по умолчанию их мир на c# пошатнулся. Для них в голове интерфейс был абстракцией . Теперь каждый junior пытается пропехнуть эту в проду.
Так нормальный мы холивар развели в комментариях по языку c# под видео на питоне.))
когда из базой данных получили данные и вернули в интерфейсе через
return result.all()
вот такая ошибка
raise ValueError(errors) from e
ValueError: [TypeError('cannot convert dictionary update sequence element #0 to a sequence'), TypeError('vars() argument must have __dict__ attribute')]
то есть не принимает dict
result.mappings().all() решает вопрос:) (у самого была такая проблема и ответ нашел здесь в кометах)
@@user-tv9fv2el8u у меня тоже самое, mappings() помог, а что это? почему так происходит?
@@user-tv9fv2el8uТолько он выводит пустой список.
после реструктуризации проекта у Артёма на гитхабе и в видео импорт происходит так:
from operations.models import operation
у меня только с указанием каталога src:
from src.operations.models import operation
если убрать префикс src, то возникает ошибка:
ModuleNotFoundError: No module named 'operations'
вставка файла __itit__.py ничего не изменила.
может быть, это не слишком принципиально, но хотелось бы понимать, почему у Артёма код работает
Привет, такая же проблема. Удалось выяснить почему?
@@unlessiamwrong Я тоже столкнулся с данной проблемой, одно из решения, просто скачайте с гитхаба папку с проектом 6 урока, и продолжайте обучение
@@44animexxx79 скачал (кстати, можно клонировать только весь проект, одна папка не скачивается), открываю любой файл, относительные пути не работают. нужно делать абсолютные.
возможно, потому что я работаю под Win10? у автора вроде бы Linux
Такая же беда. Я в файл __init__.py добавил следующий код:
import os
import sys
sys.path.append(os.path.join(sys.path[0], 'src'))
А приложение запускаю теперь через: uvicorn src.main:app --reload
Но почему у Артема работает и без этого, а у меня нет, я так и не понял)
Спасибо
Я тоже обратил внимание, что возникают проблемы при вставке Z в определенное время и лучше ее стирать. Разумеется в конце этого времени как описывает пример swagger.
Хороший комментарий для продвижения канала
спасибо за уроки, у меня вопрос : я не могу найти в коде место, где мы пускаем только авторизованных пользователей на путь "/operations" - помогите найти и разобраться
Thank you!
24:08 - блин, прикольно
Артём, извините что по имени, ещё таких два вопроса.
1. Будет ли рассказано про gunicorn поверх uvicorn (читал, что так делают, но так и не понял зачем)
2. Может было бы проще создавать подключение к БД через роутер on_event("startup") и закрытие через on_event("shutdown"). У кого-то видел в коде так было реализовано подключение... Заранее спасибо за ответы!
Спасибо за вопросы!
1. Для проекта с небольшим количеством пользователей и низким rps можно оставить только uvicorn. Если проект среднего размера и находится на одном сервере, Gunicorn + Uvicorn могут работать в связке, задействуя больше CPU, но обеспечивая больший rps. Если используется кубернетес, можно оставить uvicorn на каждом сервере.
Больше информации тут: fastapi.tiangolo.com/deployment/docker/#single-container и тут: stackoverflow.com/a/71546833/18406890
2. Скорее всего тут вы правы. Упомяну об этом в следующих видео
Отличный материал! А как связать модели из двух разных сервисов. Вот например, что если бы я хотел связать таблицу operation с таблицой User.
интересно почему сразу дату в миграции alembic не добавляет, в том же Laravel для каждой миграции дата и время ставится по умолчанию...
Хотя там вероятно миграции немного по другому устроены, но всё же...
В django миграции тоже нумеруются, если не ошибаюсь.
Артем, добрый день!) Подскажите, планируете ли курс делать с практическими заданиями , например на степике? Потому что таковых действительно нет)
Спасибо за идею! На степике в ближайшее время не планируется. Чтобы создать качественный курс, нужно довольно много времени и сил, чем я пока не располагаю.
почему ты изменил файлы не показывая на видео? в прошлом видео у тебя другая структура файлов, и тут ты сразу изменил не показывая как, и что изменил
Интересно на платном курсе тоже такие подставы есть, где лектор что-то делает сам, а ты потом должен догадаться что да как?
нет
Чтоб избежать sql - инъекций в сырых запросах_забудьте про f-string.
Для этого есть свой синтаксис. Например asyncgp передает данные через $1, $2 и тд
query = """SELECT some FROM some_table WHERE some = $1"""
изначально стал выстраивать структуру, и пишу с применением ооп
Ребят, я не уверен, но не лучше будет использовать структуру
Operation = OperationOrm(**new_operation.dict())
session.add_all(Operation )
await session.commit()
Урок год назад вышел, я пока не врубаю из-за отсутствия опыта что лучше делать таким образом или использовать операции select, insert и тд из алхимии.
У меня выдает 500 ошибку, если return result.all().Работает только - return result.scalars().all().Почему?
Получилось решить? у меня так же
@@ynerush Ответ в комментариях под этим видео - ua-cam.com/video/qvzQWBEBHYw/v-deo.html Если коротко, то автор использует надстройку над синтаксисом.Без нее scalars обязателен.
@@user-in1om1lx3f а что за настройка? Это из того треда на SOF? Я чет не понял, что именно приводит к такому результату?
return [dict(r._mapping) for r in result]
Может глупый вопрос, может уже многое поменялось. Но при выполнении query = select(operation).where(operation.c.type == operation_type)
result = await session.execute(query), result.all() возвращает массив кортежей, что влечёт ошибку с при передаче в return. Может кто нибудь пояснить по этому поводу? Что изменилось или я что то не так делаю?
Попробуйте result.scalars().all()
return [dict(r._mapping) for r in result]
Вопрос отличный, кучу времени убил на поиски решения...Вячеслав, спасибо за подсказдку!
хороший комментарий
Привет! Скажи, пожалуйста, а ты пробовал вместо Алхимии использовать Pony ORM? Мне кажется, с их веб-интерфейсом проектировки БД - очень удобный инструмент
Не пробовал. Пойду почитаю про него
что бы не удалять Z Column("date", type_=TIMESTAMP(timezone=True))
Хороший комментарий
Зачем такие танцы с metadata? Почему это лучше, чем просто target_metadata = Base.metadata?
36:55 ахахах :D
Добрый день, кто знает, как сделать валидацию существования внешнего ключа в БД через Pydantic? Чтоб если передаем Id внешнего ключа, которого нет в бд, не возвращала 500 ошибку.
лайк за момент 36:57-37:00😂
Привет, объясните, пожалуйста, зачем автор создаёт в src/auth/models.py сначала таблицу user, а потом ниже класс User, с точно такими же полями. Как я понимаю, класс юзер идёт в ОРМ алхимии, но зачем тогда нужна таблица? Она, если я не ошибаюсь, никуда не импортируется и не используется вовсе.
Да, она лишняя, можно обойтись классом
Автор, Я не претендую ни на какие титулы в программирование, и не являюсь программистом вовсе, смотрю подобные видео для саморазвития, и так, написать какую-нибудь штуку и посмотреть - заработает или нет.
Я в упор не понимаю для чего эти миграции. Почему нельзя в базе данных (MySQL, SQLite, Postgress - админке) напрямую не задать нужные таблицы и связи ? ведь работы прописывая их в "миграциях" и в интерфейсе программы администрирования БД столько же. Вот никогда не понимал этого прикола
Когда разрабатываешь бэкенд и бд в одиночку, пожалуй, миграции будут лишним грузом. Но когда бэкендеров больше, чем 2 (пускай один разрабатывает бэкенд и бд, а остальной(ые) только бэкенд), то резко увеличивается количество времени, затрачиваемое на обмен информацией об обновлении таблиц в базе данных. Таким образом, конструируя базу данных прямо на бэкенде, разработчики могут в любой момент увидеть текущее состояние бд, а также все предыдущие, не залезая в саму базу и не мучая администратора бд своими вопросами :)
Помимо этого, часто коммерческие продукты имеют версии (1.0, 2.0 и и т.д.), которые удобно поддерживать через миграции
@@artemshumeiko теперь стало понятно. Спасибо!