SQLAlchemy - это один из самых популярных ORM для работы с базами данных из Python.
- поддерживат все популярные базы данных
- не привязана к какому-либо фреймворку (как, например, Django ORM)
- поддерживает асинхрон
- позволяет удобно (питонично) делать довольно сложные SQL запросы
15 июля вышла первая версия из ветки 2.0 и это хорошйи повод изучить эту библиотеку если еще не начали.
Подобрал вам ресурсы для изучения:
- Вебинар и урок про новую SQLAlchemy2.0 от Mike Bayer (автор sqlalchemy и alembic ) с онлайн конференции pythonwebconf:
https://www.youtube.com/watch?v=Uym2DHnUEno
- Для тех кто на английском не очень, есть онлайн книга на руссом от https://xn--r1a.website/massonnn_yt.
А так же видео версия:
https://www.youtube.com/watch?v=leeC0fpAY-E&list=PLN0sMOjX-lm5Pz5EeX1rb3yilzMNT6qLM
Лично я использую алхимию в связке с FastAPI и пока всё устраивает
#tricks #libs
- поддерживат все популярные базы данных
- не привязана к какому-либо фреймворку (как, например, Django ORM)
- поддерживает асинхрон
- позволяет удобно (питонично) делать довольно сложные SQL запросы
15 июля вышла первая версия из ветки 2.0 и это хорошйи повод изучить эту библиотеку если еще не начали.
Подобрал вам ресурсы для изучения:
- Вебинар и урок про новую SQLAlchemy2.0 от Mike Bayer (автор sqlalchemy и alembic ) с онлайн конференции pythonwebconf:
https://www.youtube.com/watch?v=Uym2DHnUEno
- Для тех кто на английском не очень, есть онлайн книга на руссом от https://xn--r1a.website/massonnn_yt.
А так же видео версия:
https://www.youtube.com/watch?v=leeC0fpAY-E&list=PLN0sMOjX-lm5Pz5EeX1rb3yilzMNT6qLM
Лично я использую алхимию в связке с FastAPI и пока всё устраивает
#tricks #libs
www.sqlalchemy.org
The Database Toolkit for Python
👍22
Как проверить является ли директория пустой?
Самый простой способ:
Во втором случае мы получаем генератор, который под капотом использует тот же
Теперь представим что в директории 10к файлов
Для того чтобы ускорить проверку лучше воспользоваться функцией os.scandir(). Она работает на много быстрей и возвращает итератор с объектами os.DirEntry.
Чтобы узнать есть ли в директории хоть один файл достаточно использовать функцию
Самый простой способ:
if os.listdir(path):Тоже самое с
...
pathlib
p = Path(path)В первом случае функция
if list(p.iterdir()):
...
os.listdir возвращает полный список файлов. Нам остаётся проверить есть ли там что-либо.Во втором случае мы получаем генератор, который под капотом использует тот же
listdir.Теперь представим что в директории 10к файлов
for i in range(10000):Не сказать, что при наличии SSD это проблема, но когда таких операций много, мы начинаем терять время, особенно с
Path(f'/tmp/test/test{i}.txt').touch()
pathlib.import timeitТо есть мы получаем список всех 10к файлов просто чтобы узнать что там есть файлы. Хотя нам надо узнать есть ли по указанному пути хотя бы один файл.
test_path = '/tmp/test'
count = 1000
>>> timeit.timeit('list(os.listdir(p))', setup=f'import os;p="{test_path}"', number=count)
2.281363710993901
>>> timeit.timeit('list(p.iterdir())', setup=f'from pathlib import Path;p=Path("{test_path}")', number=count)
5.6957218300012755
Для того чтобы ускорить проверку лучше воспользоваться функцией os.scandir(). Она работает на много быстрей и возвращает итератор с объектами os.DirEntry.
Чтобы узнать есть ли в директории хоть один файл достаточно использовать функцию
next()
next(os.scandir(path))Но если директория пустая, то мы получим ошибку. Поэтому добавляем значение по умолчанию и можно использовать конструкцию в условном операторе
if next(os.scandir(path), None):Либо используем функцию
...
any(), так как она завершится сразу после нахождения первого файла или если итератор пуст.if any(os.scandir(path)):Сравним скорость
...
>>> timeit.timeit('next(os.scandir(p), None)', setup=f'import os;p="{test_path}"', number=count)
0.2183076049986994
>>> timeit.timeit('any(os.scandir(p))', setup=f'import os;p="{test_path}"', number=count)
0.21016486900043674
#tricksPython documentation
os — Miscellaneous operating system interfaces
Source code: Lib/os.py This module provides a portable way of using operating system dependent functionality. If you just want to read or write a file see open(), if you want to manipulate paths, s...
👍16❤4
Функция
Ранее я писал про функцию
Скорее всего вы уже знаете как использовать функцию
dir() - удобна для получения списка атрибутов у любого объекта.Ранее я писал про функцию
__dir__() в модуле (не путайте её с переменной __all__(), которая указывает список объектов для импорта если встречается конструкция from module import *). Скорее всего вы уже знаете как использовать функцию
dir(). Любой объект может реализовать метод __dir__() чтобы указать список имеющийхся и динамических атрибутов. И функция dir() поможет получить список этих атрибутов.>>> dir(str)У этой функции есть еще один способ применения. Её можно вызвать без аргумента, и в таком случае она вернёт список имён в текущем неймспейсе.
['__add__', '__class__', '__contains__', ...]
>>> dir()#basic #tricks
['__builtins__', '__doc__', '__file__', ...]
>>> def test():
>>> x = 1
>>> print(dir())
>>> test()
['x']
Telegram
Python Заметки
Знаете ли вы про "магические" методы классов ˍˍgetattributeˍˍ() и ˍˍgetattrˍˍ()?
ˍˍgetattributeˍˍ вызывается всякий раз когда идёт обращение к атрибуту объекта. Например метод или какая-то переменная.
ˍˍgetattrˍˍ вызывается когда атрибут не найден.
И…
ˍˍgetattributeˍˍ вызывается всякий раз когда идёт обращение к атрибуту объекта. Например метод или какая-то переменная.
ˍˍgetattrˍˍ вызывается когда атрибут не найден.
И…
👍7
Что позволяет делать f-strings в 3.12.
▫️можно использовать одинаковые кавычки во всём выражении
▫️можно добавлять переносы для многострочного выражения
▫️можно использовать символ новой строки (эта проблема неактуальна)
▫️можно использовать одинаковые кавычки во всём выражении
▫️можно добавлять переносы для многострочного выражения
▫️можно использовать символ новой строки (эта проблема неактуальна)
>>> print(f"{"\n".join(
>>> ["1","2","3",
>>> f"{
>>> f"{2+2}"
>>> *(2+2)
>>> }"
>>> ]
>>> )}")
1
2
3
4444
#tricks #libsPython documentation
2. Lexical analysis
A Python program is read by a parser. Input to the parser is a stream of tokens, generated by the lexical analyzer(also known as the tokenizer). This chapter describes how the lexical analyzer prod...
👍12
Варианты распаковки контейнеров по отдельным переменным
Обычная распаковка по точному количеству
Распаковка с неизвестным количество но не меньше чем N
Если точно знаете позицию нужного объекта в списке, включая вложенные списки, то достать его можно двумя способами
Через индекс:
Через распаковку со скобками:
Еще примеры распаковки вложенных объектов
#tricks
Обычная распаковка по точному количеству
data = [1, 2, 3, 4, 5]
v1, v2, v3, v4, v5 = data
Распаковка с неизвестным количество но не меньше чем N
v1, *_ = data
v1, *_, v4, v5 = data
Если точно знаете позицию нужного объекта в списке, включая вложенные списки, то достать его можно двумя способами
Через индекс:
data = [[1]]
v1 = data[0][0]
Через распаковку со скобками:
data = [[1]]
(v1, ), = data
data = [[[1]]]
((v1,), ), = data
Еще примеры распаковки вложенных объектов
data = [[1, 2], [3, 4], [5, 6]]
(v1, v2), (v3, v4), (v5, v6) = data
(v1, v2), *_, (v5, *_) = data
#tricks
🔥16👍6
Когда пишешь асинхронный код нужно учитывать особенности такого подхода. Всегда требуется держать в уме, когда возвращается корутина а когда реальный результат. Между этими двумя сущностями должен быть вызов через
Вот пример синхронного запроса в базу данных с помощь sqlalchemy. Query пишу инлайном для компактности.
Всё ясно и линейно. А вот он же асинхронный.
Это значит что
Не хочу сказать что это мастхэв практика, но простые асинхронные запросы тоже можно сократить до одной строки. Просто использовать скобки.
На самом деле я использую такую конструкцию только в прототипах тестов или вспомогательных функциях тестов. В продакшн такое обычно не попадает.
#tricks
await.Вот пример синхронного запроса в базу данных с помощь sqlalchemy. Query пишу инлайном для компактности.
entities = session.execute(select(EntityModel)).scalars().all()
Всё ясно и линейно. А вот он же асинхронный.
result = await session.execute(select(EntityModel))
entities = result.scalars().all()
Это значит что
session.execute возвращает корутину, или awaitable объект. Сначала его нужно выполнить через await, тогда получишь объект с которым можно дальше работать.Не хочу сказать что это мастхэв практика, но простые асинхронные запросы тоже можно сократить до одной строки. Просто использовать скобки.
entities = ( await session.execute(select(EntityModel)) ).scalars().all()
На самом деле я использую такую конструкцию только в прототипах тестов или вспомогательных функциях тестов. В продакшн такое обычно не попадает.
#tricks
👍9