<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Разработка Telegram-ботов</title><subtitle>В основном рабочие и технические заметки</subtitle><author><name>Разработка Telegram-ботов</name></author><id>https://teletype.in/atom/tgdev</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/tgdev?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@tgdev?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=tgdev"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/tgdev?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-19T22:09:47.972Z</updated><entry><id>tgdev:HTvs0Ei4EIv</id><link rel="alternate" type="text/html" href="https://teletype.in/@tgdev/HTvs0Ei4EIv?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=tgdev"></link><title>SQLAlchemy: разница между result.scalars().all()  и result.all()</title><published>2025-01-22T19:56:18.066Z</published><updated>2025-01-22T19:56:18.066Z</updated><category term="ainotes" label="AI Notes"></category><tt:hashtag>chatgpt</tt:hashtag><tt:hashtag>python</tt:hashtag><tt:hashtag>orm</tt:hashtag><tt:hashtag>sqlalchemy</tt:hashtag><summary type="html">Разница между result.scalars().all() и result.all() заключается в том, как эти методы обрабатывают результат выполнения запроса SQLAlchemy. Они возвращают разные типы данных, что влияет на удобство работы с результатами.</summary><content type="html">
  &lt;p id=&quot;hKwS&quot;&gt;Разница между &lt;code&gt;result.scalars().all()&lt;/code&gt; и &lt;code&gt;result.all()&lt;/code&gt; заключается в том, как эти методы обрабатывают результат выполнения запроса SQLAlchemy. Они возвращают разные типы данных, что влияет на удобство работы с результатами.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;2Ltu&quot;&gt;&lt;strong&gt;1. &lt;code&gt;result.all()&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
  &lt;ul id=&quot;K1tT&quot;&gt;
    &lt;li id=&quot;bGCB&quot;&gt;Возвращает &lt;strong&gt;список кортежей&lt;/strong&gt;, где каждый кортеж представляет строку результата запроса.&lt;/li&gt;
    &lt;li id=&quot;ki57&quot;&gt;Используется, если в запросе есть несколько столбцов или вы явно запрашиваете несколько объектов.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h4 id=&quot;V56L&quot;&gt;Пример:&lt;/h4&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;KTPa&quot; data-lang=&quot;python&quot;&gt;query = select(UserAdm, ChatAdm).join(Link, Link.user_id == UserAdm.id).join(ChatAdm, Link.chat_id == ChatAdm.id)
result = await session.execute(query)
data = result.all()

print(data)
# [(&amp;lt;UserAdm&amp;gt;, &amp;lt;ChatAdm&amp;gt;), (&amp;lt;UserAdm&amp;gt;, &amp;lt;ChatAdm&amp;gt;)]
&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;RjYr&quot;&gt;&lt;strong&gt;Когда использовать&lt;/strong&gt;:&lt;/p&gt;
  &lt;ul id=&quot;7TRX&quot;&gt;
    &lt;li id=&quot;Rwz8&quot;&gt;Когда запрос возвращает несколько объектов или столбцов в строке.&lt;/li&gt;
    &lt;li id=&quot;FMds&quot;&gt;Если нужна информация обо всех возвращённых данных.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;zE4T&quot;&gt;&lt;strong&gt;2. &lt;code&gt;result.scalars().all()&lt;/code&gt;&lt;/strong&gt;&lt;/h3&gt;
  &lt;ul id=&quot;14Tf&quot;&gt;
    &lt;li id=&quot;AL1W&quot;&gt;Возвращает &lt;strong&gt;список объектов&lt;/strong&gt; из одной конкретной колонки (или объекта), заданной в &lt;code&gt;select()&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;NlYj&quot;&gt;Если вы запрашиваете только один объект или колонку, этот метод &amp;quot;распаковывает&amp;quot; результаты, убирая обёртку кортежей.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h4 id=&quot;hnGL&quot;&gt;Пример:&lt;/h4&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;ZeWt&quot; data-lang=&quot;python&quot;&gt;query = select(ChatAdm).join(Link, Link.chat_id == ChatAdm.id)
result = await session.execute(query)
data = result.scalars().all()

print(data)
# [&amp;lt;ChatAdm&amp;gt;, &amp;lt;ChatAdm&amp;gt;]
&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;OphE&quot;&gt;&lt;strong&gt;Когда использовать&lt;/strong&gt;:&lt;/p&gt;
  &lt;ul id=&quot;CchI&quot;&gt;
    &lt;li id=&quot;OcQ2&quot;&gt;Когда запрос возвращает один объект или одну колонку.&lt;/li&gt;
    &lt;li id=&quot;rxsn&quot;&gt;Это делает код чище, так как нет необходимости разбирать кортежи.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;TNZx&quot;&gt;&lt;strong&gt;Ключевые различия:&lt;/strong&gt;&lt;/h3&gt;
  &lt;p id=&quot;tWh6&quot;&gt;&lt;strong&gt;Метод:&lt;/strong&gt; &lt;code&gt;result.all()&lt;/code&gt; &lt;br /&gt;&lt;strong&gt;Возвращаемое значение:&lt;/strong&gt; Список кортежей (строк результата запроса)&lt;br /&gt;&lt;strong&gt;Когда использовать:&lt;/strong&gt; Если запрос возвращает несколько объектов или колонок.&lt;/p&gt;
  &lt;p id=&quot;blGj&quot;&gt;&lt;strong&gt;Метод:&lt;/strong&gt; &lt;code&gt;result.scalars().all()&lt;/code&gt; &lt;br /&gt;&lt;strong&gt;Возвращаемое значение: &lt;/strong&gt;Список объектов или значений из одной выбранной колонки. &lt;br /&gt;&lt;strong&gt;Когда использовать: &lt;/strong&gt;Если нужен только один объект или колонка.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;cew3&quot;&gt;&lt;strong&gt;Пример для сравнения:&lt;/strong&gt;&lt;/h3&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;fxFr&quot; data-lang=&quot;python&quot;&gt;# Запрос с несколькими столбцами
query = select(UserAdm, ChatAdm).join(Link, Link.user_id == UserAdm.id).join(ChatAdm, Link.chat_id == ChatAdm.id)

result = await session.execute(query)

# Используем result.all()
data_all = result.all()
print(data_all)  # [(&amp;lt;UserAdm&amp;gt;, &amp;lt;ChatAdm&amp;gt;), (&amp;lt;UserAdm&amp;gt;, &amp;lt;ChatAdm&amp;gt;)]

# Используем result.scalars().all()
data_scalars = result.scalars().all()  # Ошибка, так как запрос возвращает несколько столбцов
&lt;/pre&gt;
  &lt;/section&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;qXtH&quot; data-lang=&quot;python&quot;&gt;# Запрос с одним объектом
query = select(ChatAdm).join(Link, Link.chat_id == ChatAdm.id)

result = await session.execute(query)

# Используем result.all()
data_all = result.all()
print(data_all)  # [(&amp;lt;ChatAdm&amp;gt;,), (&amp;lt;ChatAdm&amp;gt;,)]

# Используем result.scalars().all()
data_scalars = result.scalars().all()
print(data_scalars)  # [&amp;lt;ChatAdm&amp;gt;, &amp;lt;ChatAdm&amp;gt;]
&lt;/pre&gt;
  &lt;/section&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;xbW8&quot;&gt;Резюме:&lt;/h3&gt;
  &lt;ul id=&quot;HyZO&quot;&gt;
    &lt;li id=&quot;9Bo2&quot;&gt;&lt;strong&gt;Используйте &lt;code&gt;result.scalars().all()&lt;/code&gt;&lt;/strong&gt;, если запрос возвращает &lt;strong&gt;один объект или одну колонку&lt;/strong&gt;, так как это упрощает работу с результатами.&lt;/li&gt;
    &lt;li id=&quot;0ncl&quot;&gt;&lt;strong&gt;Используйте &lt;code&gt;result.all()&lt;/code&gt;&lt;/strong&gt;, если запрос возвращает &lt;strong&gt;несколько объектов или колонок&lt;/strong&gt;, чтобы сохранить все данные.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;q8cZ&quot;&gt;&lt;/p&gt;
  &lt;tt-tags id=&quot;DiYp&quot;&gt;
    &lt;tt-tag name=&quot;chatgpt&quot;&gt;#chatgpt&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;python&quot;&gt;#python&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;orm&quot;&gt;#orm&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;sqlalchemy&quot;&gt;#sqlalchemy&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>tgdev:getme</id><link rel="alternate" type="text/html" href="https://teletype.in/@tgdev/getme?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=tgdev"></link><title>Кэширование bot.get_me()</title><published>2025-01-20T00:52:02.866Z</published><updated>2025-01-20T00:52:02.866Z</updated><category term="ainotes" label="AI Notes"></category><tt:hashtag>chatgpt</tt:hashtag><tt:hashtag>python</tt:hashtag><tt:hashtag>aiogram</tt:hashtag><summary type="html">Метод bot.me() в Aiogram используется для получения информации о самом боте, аналогично вызову bot.get_me(). Однако, главное отличие заключается в том, что bot.me() возвращает закешированное значение, если оно уже было загружено.</summary><content type="html">
  &lt;p id=&quot;PZdk&quot;&gt;Метод &lt;code&gt;bot.me()&lt;/code&gt; в Aiogram используется для получения информации о самом боте, аналогично вызову &lt;code&gt;bot.get_me()&lt;/code&gt;. Однако, главное отличие заключается в том, что &lt;code&gt;bot.me()&lt;/code&gt; &lt;strong&gt;возвращает закешированное значение&lt;/strong&gt;, если оно уже было загружено.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;JH1B&quot;&gt;Как работает &lt;code&gt;bot.me()&lt;/code&gt;?&lt;/h3&gt;
  &lt;ol id=&quot;Zwmd&quot;&gt;
    &lt;li id=&quot;XBHE&quot;&gt;&lt;strong&gt;Первый вызов &lt;code&gt;bot.get_me()&lt;/code&gt;&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;UgI3&quot;&gt;
      &lt;li id=&quot;wbGR&quot;&gt;Когда вы вызываете &lt;code&gt;bot.get_me()&lt;/code&gt;, Aiogram отправляет запрос в Telegram API на получение информации о боте. Этот запрос возвращает объект &lt;code&gt;aiogram.types.User&lt;/code&gt;, содержащий данные о боте (например, &lt;code&gt;id&lt;/code&gt;, &lt;code&gt;username&lt;/code&gt;, &lt;code&gt;first_name&lt;/code&gt;).&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;Ckhr&quot;&gt;&lt;strong&gt;Кеширование результата&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;Xy5d&quot;&gt;
      &lt;li id=&quot;Y4Nr&quot;&gt;Aiogram автоматически сохраняет полученный объект в атрибуте &lt;code&gt;bot._me&lt;/code&gt;. Это значение сохраняется в памяти до завершения работы приложения.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;cnE2&quot;&gt;&lt;strong&gt;Вызов &lt;code&gt;bot.me()&lt;/code&gt;&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;mhAg&quot;&gt;
      &lt;li id=&quot;QF0F&quot;&gt;Когда вы вызываете &lt;code&gt;bot.me()&lt;/code&gt;, метод проверяет, было ли ранее закешировано значение в &lt;code&gt;bot._me&lt;/code&gt;.&lt;/li&gt;
      &lt;li id=&quot;7w5D&quot;&gt;Если значение закешировано, метод возвращает его без нового запроса к Telegram API.&lt;/li&gt;
      &lt;li id=&quot;2yXM&quot;&gt;Если значение отсутствует, &lt;code&gt;bot.me()&lt;/code&gt; вызывает &lt;code&gt;bot.get_me()&lt;/code&gt; для получения данных, а затем сохраняет результат в &lt;code&gt;bot._me&lt;/code&gt;.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;Uckp&quot;&gt;Пример использования &lt;code&gt;bot.me()&lt;/code&gt;&lt;/h3&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;a4qO&quot; data-lang=&quot;python&quot;&gt;from aiogram import Bot
from aiogram.types import User

async def get_bot_info(bot: Bot) -&amp;gt; User:
    me = await bot.me()  # Использует закешированное значение или отправляет запрос к Telegram
    return me&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;bnRU&quot;&gt;При первом вызове &lt;code&gt;await bot.me()&lt;/code&gt;, бот отправит запрос к Telegram, но последующие вызовы вернут закешированное значение, что экономит ресурсы.&lt;/p&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;gvyI&quot;&gt;Когда использовать &lt;code&gt;bot.me()&lt;/code&gt; вместо &lt;code&gt;bot.get_me()&lt;/code&gt;?&lt;/h3&gt;
  &lt;ul id=&quot;967R&quot;&gt;
    &lt;li id=&quot;Og3b&quot;&gt;&lt;strong&gt;Используйте &lt;code&gt;bot.me()&lt;/code&gt;&lt;/strong&gt;, если вам нужно получить информацию о боте несколько раз за сессию.&lt;/li&gt;
    &lt;ul id=&quot;h7da&quot;&gt;
      &lt;li id=&quot;I7hH&quot;&gt;Например, вы хотите использовать имя или ID бота в разных хендлерах, но эти данные не меняются на протяжении работы приложения.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;pryD&quot;&gt;&lt;strong&gt;Используйте &lt;code&gt;bot.get_me()&lt;/code&gt;&lt;/strong&gt;, если вы хотите быть уверены, что данные о боте актуальны.&lt;/li&gt;
    &lt;ul id=&quot;zHpD&quot;&gt;
      &lt;li id=&quot;Njnf&quot;&gt;Например, если бот мог быть переименован или поменял username, а вы хотите получить свежие данные (это редкий случай).&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;9boC&quot;&gt;Как минимизировать количество запросов к Telegram?&lt;/h3&gt;
  &lt;p id=&quot;9Fjd&quot;&gt;Если вы хотите снизить количество запросов, то использование &lt;code&gt;bot.me()&lt;/code&gt; — лучший вариант, поскольку:&lt;/p&gt;
  &lt;ol id=&quot;lvFo&quot;&gt;
    &lt;li id=&quot;kTwk&quot;&gt;Первый запрос сохраняется в кеше.&lt;/li&gt;
    &lt;li id=&quot;LgKd&quot;&gt;Повторные вызовы используют локальное значение.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;huua&quot;&gt;Как кешировать данные о боте при старте?&lt;/h3&gt;
  &lt;p id=&quot;cwVI&quot;&gt;Если вы уверены, что данные о боте не изменятся во время работы, вы можете вызвать &lt;code&gt;await bot.me()&lt;/code&gt; один раз при старте приложения, чтобы данные оказались закешированными. Например:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre id=&quot;NJuP&quot; data-lang=&quot;python&quot;&gt;async def main():
    bot = Bot(token=TOKEN)
    
    # Закешировать информацию о боте
    await bot.me()
    
    # Теперь любые вызовы bot.me() будут использовать кеш
    ...&lt;/pre&gt;
  &lt;/section&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;wwH1&quot;&gt;Итог&lt;/h3&gt;
  &lt;p id=&quot;5HQj&quot;&gt;Использование &lt;code&gt;bot.me()&lt;/code&gt; позволяет эффективно кешировать информацию о боте и уменьшить количество запросов к Telegram API. Если вы хотите ещё больше контроля, можно вызвать &lt;code&gt;await bot.me()&lt;/code&gt; один раз при инициализации и использовать этот кеш во всех хендлерах.&lt;/p&gt;
  &lt;p id=&quot;GAbP&quot;&gt;&lt;/p&gt;
  &lt;tt-tags id=&quot;uJ0X&quot;&gt;
    &lt;tt-tag name=&quot;chatgpt&quot;&gt;#chatgpt&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;python&quot;&gt;#python&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;aiogram&quot;&gt;#aiogram&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>tgdev:orm-basic</id><link rel="alternate" type="text/html" href="https://teletype.in/@tgdev/orm-basic?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=tgdev"></link><title>ORM методы</title><published>2025-01-19T23:41:52.268Z</published><updated>2025-01-19T23:41:52.268Z</updated><category term="ainotes" label="AI Notes"></category><tt:hashtag>chatgpt</tt:hashtag><tt:hashtag>python</tt:hashtag><tt:hashtag>orm</tt:hashtag><tt:hashtag>sqlalchemy</tt:hashtag><summary type="html">Использование ORM-методов в SQLAlchemy предполагает работу с объектами классов (моделей), которые представляют строки таблиц базы данных. Вместо написания SQL-запросов вы работаете с объектами, их атрибутами и методами. Это делает код более читаемым и легко поддерживаемым.</summary><content type="html">
  &lt;p id=&quot;uekR&quot;&gt;Использование ORM-методов в SQLAlchemy предполагает работу с объектами классов (моделей), которые представляют строки таблиц базы данных. Вместо написания SQL-запросов вы работаете с объектами, их атрибутами и методами. Это делает код более читаемым и легко поддерживаемым.&lt;/p&gt;
  &lt;h2 id=&quot;ILwm&quot;&gt;Основные этапы работы с ORM-методами&lt;/h2&gt;
  &lt;h3 id=&quot;vSZ1&quot;&gt;1. Создание и настройка модели&lt;/h3&gt;
  &lt;p id=&quot;SVd9&quot;&gt;Определите модели, которые будут соответствовать таблицам в базе данных. Пример:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;GmAK&quot;&gt;from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relationship
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class User(Base):
    __tablename__ = &amp;quot;users&amp;quot;
    
    id = Column(Integer, primary_key=True)
    username = Column(String, nullable=False)
    email = Column(String, unique=True)&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;YKzf&quot;&gt;2. Добавление записей&lt;/h3&gt;
  &lt;p id=&quot;DoqE&quot;&gt;Вы создаёте экземпляры классов, заполняете их атрибуты и добавляете в сессию:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;XTGv&quot;&gt;async with async_session() as session:
    new_user = User(username=&amp;quot;JohnDoe&amp;quot;, email=&amp;quot;john@example.com&amp;quot;)
    session.add(new_user)
    await session.commit()&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;eQac&quot;&gt;3. Чтение записей&lt;/h3&gt;
  &lt;p id=&quot;om0q&quot;&gt;Для получения данных вы используете запросы через session.query или session.get:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;AhPH&quot;&gt;async with async_session() as session:
    user = await session.get(User, 1)  # Получение пользователя по первичному ключу
    if user:
        print(user.username, user.email)&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;gVbP&quot;&gt;4. Обновление записей&lt;/h3&gt;
  &lt;p id=&quot;dfOK&quot;&gt;Для обновления записей достаточно изменить атрибуты объекта и вызвать session.commit:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;P36y&quot;&gt;async with async_session() as session:
    user = await session.get(User, 1)  # Находим объект
    if user:
        user.email = &amp;quot;new_email@example.com&amp;quot;  # Изменяем атрибут
        await session.commit()  # Сохраняем изменения&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;TPmB&quot;&gt;5. Удаление записей&lt;/h3&gt;
  &lt;p id=&quot;PbVt&quot;&gt;Для удаления записей используется метод session.delete:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;sJAv&quot;&gt;async with async_session() as session:
    user = await session.get(User, 1)  # Находим объект
    if user:
        await session.delete(user)  # Удаляем объект
        await session.commit()  # Сохраняем изменения&lt;/pre&gt;
  &lt;/section&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;HUDs&quot;&gt;Преимущества использования ORM-методов&lt;/h3&gt;
  &lt;ul id=&quot;rxbh&quot;&gt;
    &lt;li id=&quot;mBTc&quot;&gt;Скрытие SQL-запросов: Нет необходимости вручную писать SQL-код.&lt;/li&gt;
    &lt;li id=&quot;dgqf&quot;&gt;Интуитивность: Вы работаете с объектами Python, что делает код естественным.&lt;/li&gt;
    &lt;li id=&quot;t0m5&quot;&gt;Связи между таблицами: ORM позволяет легко работать с отношениями, например, one-to-many или many-to-many.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;Cipf&quot;&gt;Пример сложной операции&lt;/h3&gt;
  &lt;p id=&quot;E0ko&quot;&gt;Допустим, у вас есть пользователь, у которого может быть несколько постов. Нужно добавить новый пост для пользователя:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;ChGS&quot;&gt;class Post(Base):
    __tablename__ = &amp;quot;posts&amp;quot;

    id = Column(Integer, primary_key=True)
    title = Column(String, nullable=False)
    content = Column(String, nullable=False)
    user_id = Column(Integer, ForeignKey(&amp;quot;users.id&amp;quot;), nullable=False)

    user = relationship(&amp;quot;User&amp;quot;, back_populates=&amp;quot;posts&amp;quot;)

class User(Base):
    __tablename__ = &amp;quot;users&amp;quot;

    id = Column(Integer, primary_key=True)
    username = Column(String, nullable=False)
    posts = relationship(&amp;quot;Post&amp;quot;, back_populates=&amp;quot;user&amp;quot;)&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;E9um&quot;&gt;Добавим пост:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;u4rH&quot;&gt;async with async_session() as session:
    user = await session.get(User, 1)
    if user:
        new_post = Post(title=&amp;quot;My First Post&amp;quot;, content=&amp;quot;Hello, world!&amp;quot;, user_id=user.id)
        user.posts.append(new_post)  # Можно работать через &amp;#x60;relationship&amp;#x60;
        await session.commit()&lt;/pre&gt;
  &lt;/section&gt;
  &lt;hr /&gt;
  &lt;h3 id=&quot;Jxkp&quot;&gt;Рекомендации&lt;/h3&gt;
  &lt;ol id=&quot;gm7B&quot;&gt;
    &lt;li id=&quot;ghbO&quot;&gt;Работайте через relationship Используйте связи между таблицами (например, user.posts) для упрощения кода.&lt;/li&gt;
    &lt;li id=&quot;2Hbf&quot;&gt;Используйте сессии аккуратно Каждый запрос должен выполняться в пределах асинхронной сессии (async with async_session()).&lt;/li&gt;
    &lt;li id=&quot;pT0d&quot;&gt;Оптимизируйте запросы Если нужно загрузить связанные данные, используйте joinedload или selectinload:&lt;/li&gt;
  &lt;/ol&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;5Nrl&quot;&gt;from sqlalchemy.orm import joinedload

async with async_session() as session:
    user = await session.execute(
        select(User).options(joinedload(User.posts)).where(User.id == 1)
    )
    user = user.scalar_one_or_none()&lt;/pre&gt;
  &lt;/section&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;DPVl&quot;&gt;&lt;/p&gt;
  &lt;tt-tags id=&quot;P7yy&quot;&gt;
    &lt;tt-tag name=&quot;chatgpt&quot;&gt;#chatgpt&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;python&quot;&gt;#python&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;orm&quot;&gt;#orm&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;sqlalchemy&quot;&gt;#sqlalchemy&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>tgdev:WyKrUInlOMk</id><link rel="alternate" type="text/html" href="https://teletype.in/@tgdev/WyKrUInlOMk?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=tgdev"></link><title>bot: Bot в каждой функции</title><published>2025-01-19T23:39:30.798Z</published><updated>2025-01-19T23:39:30.798Z</updated><category term="ainotes" label="AI Notes"></category><tt:hashtag>chatgpt</tt:hashtag><tt:hashtag>python</tt:hashtag><tt:hashtag>aiogram</tt:hashtag><summary type="html">Чтобы не передавать объект bot: Bot в каждую функцию, можно создать глобальную переменную и инициализировать её при запуске бота. Этот подход работает, но требует осторожности, так как глобальные переменные могут усложнить тестирование и отладку.</summary><content type="html">
  &lt;p id=&quot;1mXA&quot;&gt;Чтобы не передавать объект bot: Bot в каждую функцию, можно создать глобальную переменную и инициализировать её при запуске бота. Этот подход работает, но требует осторожности, так как глобальные переменные могут усложнить тестирование и отладку.&lt;/p&gt;
  &lt;h2 id=&quot;ZQIH&quot;&gt;Решение с использованием глобальной переменной&lt;/h2&gt;
  &lt;h3 id=&quot;BKrf&quot;&gt;1. Инициализация глобальной переменной bot на уровне файла functions.py:&lt;/h3&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;R5wc&quot;&gt;from aiogram import Bot

# Глобальная переменная для хранения экземпляра бота
bot: Bot | None = None

def set_bot_instance(bot_instance: Bot):
    &amp;quot;&amp;quot;&amp;quot;
    Устанавливает глобальный экземпляр бота.
    &amp;quot;&amp;quot;&amp;quot;
    global bot
    bot = bot_instance&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;ONMi&quot;&gt;2. Инициализация в основном файле bot.py:&lt;/h3&gt;
  &lt;p id=&quot;nZzu&quot;&gt;При запуске бота установите экземпляр глобального объекта:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;CkNZ&quot;&gt;from aiogram import Bot
from functions import set_bot_instance

async def main():
    bot = Bot(token=TOKEN)
    set_bot_instance(bot)  # Передаём экземпляр бота в functions.py
    ...&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;PSPE&quot;&gt;3. Использование глобального bot в functions.py:&lt;/h3&gt;
  &lt;p id=&quot;UVje&quot;&gt;Теперь во всех функциях внутри functions.py вы можете обращаться к глобальной переменной bot напрямую:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;1pqu&quot;&gt;from aiogram import types
from . import bot  # Импорт глобальной переменной bot

async def send_message_to_user(chat_id: int, text: str):
    &amp;quot;&amp;quot;&amp;quot;
    Отправляет сообщение пользователю.
    &amp;quot;&amp;quot;&amp;quot;
    if bot is None:
        raise RuntimeError(&amp;quot;Bot instance is not initialized!&amp;quot;)
    await bot.send_message(chat_id=chat_id, text=text)&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;xbKR&quot;&gt;Плюсы подхода:&lt;/h3&gt;
  &lt;ol id=&quot;ln71&quot;&gt;
    &lt;li id=&quot;tT71&quot;&gt;Уменьшение количества передаваемых аргументов.&lt;/li&gt;
    &lt;ul id=&quot;fvg2&quot;&gt;
      &lt;li id=&quot;7tj3&quot;&gt;Не нужно передавать bot в каждую функцию.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;SMmw&quot;&gt;Централизованное управление объектом.&lt;/li&gt;
    &lt;ul id=&quot;e0ZN&quot;&gt;
      &lt;li id=&quot;eW5g&quot;&gt;Экземпляр бота можно легко обновить или заменить, если потребуется.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;h3 id=&quot;0szt&quot;&gt;Минусы подхода:&lt;/h3&gt;
  &lt;ol id=&quot;LxCI&quot;&gt;
    &lt;li id=&quot;jbLs&quot;&gt;Зависимость от глобальной переменной:&lt;/li&gt;
    &lt;ul id=&quot;cVsR&quot;&gt;
      &lt;li id=&quot;SDT5&quot;&gt;Усложняется тестирование функций, так как нужно явно инициализировать bot перед вызовами.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;wEts&quot;&gt;Потенциальные проблемы с многопоточностью:&lt;/li&gt;
    &lt;ul id=&quot;RAyA&quot;&gt;
      &lt;li id=&quot;vbyq&quot;&gt;Если ваш код работает в асинхронной среде, использование глобальной переменной может привести к неожиданным ошибкам, если вы одновременно запустите несколько экземпляров бота.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;h3 id=&quot;iCAP&quot;&gt;Альтернативный подход: Контекст&lt;/h3&gt;
  &lt;p id=&quot;BNBR&quot;&gt;Если глобальные переменные кажутся неудобными, можно использовать контекст для хранения bot:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;4hZC&quot;&gt;from contextvars import ContextVar
from aiogram import Bot

bot_context: ContextVar[Bot] = ContextVar(&amp;quot;bot&amp;quot;)

def set_bot_instance(bot_instance: Bot):
    bot_context.set(bot_instance)
    
def get_bot_instance() -&amp;gt; Bot:
    return bot_context.get()&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;UyeX&quot;&gt;Использование:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;jeqy&quot;&gt;async def send_message_to_user(chat_id: int, text: str):
    bot = get_bot_instance()
    await bot.send_message(chat_id=chat_id, text=text)&lt;/pre&gt;
  &lt;/section&gt;
  &lt;p id=&quot;lYaO&quot;&gt;Этот подход безопаснее для многопоточной среды.&lt;/p&gt;
  &lt;p id=&quot;iQFo&quot;&gt;&lt;/p&gt;
  &lt;tt-tags id=&quot;pYYY&quot;&gt;
    &lt;tt-tag name=&quot;chatgpt&quot;&gt;#chatgpt&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;python&quot;&gt;#python&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;aiogram&quot;&gt;#aiogram&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry><entry><id>tgdev:alembic-basic</id><link rel="alternate" type="text/html" href="https://teletype.in/@tgdev/alembic-basic?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=tgdev"></link><title>Alembic миграции</title><published>2025-01-19T23:33:42.700Z</published><updated>2025-01-19T23:33:42.700Z</updated><category term="ainotes" label="AI Notes"></category><tt:hashtag>chatgpt</tt:hashtag><tt:hashtag>python</tt:hashtag><tt:hashtag>alembic</tt:hashtag><summary type="html">Для инициализации данных в таблицах базы данных PostgreSQL с использованием SQLAlchemy и Alembic, рекомендуется использовать Alembic миграции.</summary><content type="html">
  &lt;p id=&quot;xbQ0&quot;&gt;Для инициализации данных в таблицах базы данных PostgreSQL с использованием SQLAlchemy и Alembic, рекомендуется использовать Alembic миграции. Это позволит создавать начальные данные в таблице при выполнении миграций.&lt;/p&gt;
  &lt;p id=&quot;bjWx&quot;&gt;Вот пошаговый подход для добавления первых данных в таблицу:&lt;/p&gt;
  &lt;h3 id=&quot;GpYS&quot;&gt;1. Создайте миграцию с Alembic&lt;/h3&gt;
  &lt;p id=&quot;yzDa&quot;&gt;Используйте команду &lt;code&gt;alembic revision --autogenerate -m &amp;quot;Добавление начальных данных&amp;quot;&lt;/code&gt; или создайте новую миграцию вручную:&lt;/p&gt;
  &lt;p id=&quot;4e96&quot;&gt;&lt;code&gt;alembic revision -m &amp;quot;Добавление начальных данных&amp;quot;&lt;/code&gt;&lt;/p&gt;
  &lt;h3 id=&quot;UeYB&quot;&gt;2. Добавьте код для вставки данных в миграцию&lt;/h3&gt;
  &lt;p id=&quot;HPv6&quot;&gt;В созданном файле миграции найдите функцию upgrade и добавьте SQL-запросы или ORM-операции для вставки данных.&lt;/p&gt;
  &lt;p id=&quot;Wtqk&quot;&gt;Пример файла миграции (&lt;code&gt;&amp;lt;timestamp&amp;gt;_добавление_начальных_данных.py&lt;/code&gt;):&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;YC3a&quot;&gt;from alembic import op
import sqlalchemy as sa

# revision identifiers, used by Alembic.
revision = &amp;#x27;&amp;lt;revision_id&amp;gt;&amp;#x27;
down_revision = &amp;#x27;&amp;lt;previous_revision_id&amp;gt;&amp;#x27;
branch_labels = None
depends_on = None

def upgrade():
    # Добавление начальных данных
    conn = op.get_bind()
    conn.execute(
        sa.text(
            &amp;quot;INSERT INTO settings (key, value) VALUES (:key, :value) ON CONFLICT (key) DO NOTHING&amp;quot;
        ),
        [{&amp;quot;key&amp;quot;: &amp;quot;is_mode_get_user_id&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;0&amp;quot;},
         {&amp;quot;key&amp;quot;: &amp;quot;get_user_id_message&amp;quot;, &amp;quot;value&amp;quot;: &amp;quot;😶😶😶&amp;quot;}]
    )
    
def downgrade():
    # Удаление данных (опционально, если требуется при откате)
    conn = op.get_bind()
    conn.execute(
        sa.text(&amp;quot;DELETE FROM settings WHERE key IN (:keys)&amp;quot;),
        {&amp;quot;keys&amp;quot;: (&amp;quot;is_mode_get_user_id&amp;quot;, &amp;quot;get_user_id_message&amp;quot;)}
    )

&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;xcZ3&quot;&gt;3. Обновите базу данных с помощью Alembic&lt;/h3&gt;
  &lt;p id=&quot;9Qya&quot;&gt;Примените новую миграцию, выполнив:&lt;/p&gt;
  &lt;p id=&quot;6TgJ&quot;&gt;&lt;code&gt;alembic upgrade head&lt;/code&gt;&lt;/p&gt;
  &lt;h3 id=&quot;Sxw1&quot;&gt;Пояснение:&lt;/h3&gt;
  &lt;ol id=&quot;RZKE&quot;&gt;
    &lt;li id=&quot;mhSN&quot;&gt;&lt;code&gt;conn = op.get_bind()&lt;/code&gt;: Получает соединение с базой данных для выполнения SQL-запросов напрямую.&lt;/li&gt;
    &lt;li id=&quot;cPTp&quot;&gt;&lt;code&gt;ON CONFLICT (key) DO NOTHING&lt;/code&gt;: PostgreSQL-конструкция для игнорирования ошибок вставки, если запись с таким ключом уже существует (аналогично &lt;code&gt;INSERT OR IGNORE&lt;/code&gt; в SQLite).&lt;/li&gt;
    &lt;li id=&quot;zCjk&quot;&gt;Использование &lt;code&gt;sa.text&lt;/code&gt;: Позволяет вставлять данные через сырые SQL-запросы с поддержкой параметров.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h3 id=&quot;v8rU&quot;&gt;Альтернативный подход через ORM (опционально)&lt;/h3&gt;
  &lt;p id=&quot;r2zF&quot;&gt;Если вы хотите использовать SQLAlchemy ORM вместо сырых SQL-запросов, можно выполнить инициализацию в отдельном скрипте, используя сессию:&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;UNiy&quot;&gt;from sqlalchemy.orm import Session
from your_project.models import Setting  # Импортируйте вашу ORM-модель

def initialize_settings(engine):
    with Session(engine) as session:
        # Проверяем, есть ли записи, и добавляем только если они отсутствуют
        if not session.query(Setting).filter(Setting.key == &amp;quot;is_mode_get_user_id&amp;quot;).first():
            session.add(Setting(key=&amp;quot;is_mode_get_user_id&amp;quot;, value=&amp;quot;0&amp;quot;))
        if not session.query(Setting).filter(Setting.key == &amp;quot;get_user_id_message&amp;quot;).first():
            session.add(Setting(key=&amp;quot;get_user_id_message&amp;quot;, value=&amp;quot;😶😶😶&amp;quot;))
        session.commit()&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;iZ4t&quot;&gt;Рекомендации:&lt;/h3&gt;
  &lt;ol id=&quot;D0JS&quot;&gt;
    &lt;li id=&quot;vH8p&quot;&gt;Для разового выполнения начальной инициализации используйте Alembic миграции.&lt;/li&gt;
    &lt;li id=&quot;l2AY&quot;&gt;Если данные должны проверяться и обновляться динамически, создайте отдельную функцию для инициализации, как в примере с ORM.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;DmcE&quot;&gt;Использовать Alembic или ORM для внесения начальных данных возможно, и оба подхода имеют свои плюсы. Вот детальное руководство для обоих случаев.&lt;/p&gt;
  &lt;h3 id=&quot;5Li8&quot;&gt;1. Внесение данных через Alembic&lt;/h3&gt;
  &lt;p id=&quot;UTgq&quot;&gt;В миграциях Alembic вы можете использовать SQLAlchemy ORM для работы с таблицами.&lt;/p&gt;
  &lt;p id=&quot;l0zj&quot;&gt;Пример файла миграции (&lt;code&gt;&amp;lt;timestamp&amp;gt;_добавление_данных.py&lt;/code&gt;):&lt;/p&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;UPfE&quot;&gt;from alembic import op
from sqlalchemy.orm import Session
from sqlalchemy import inspect
from your_project.models import Settings  # Импортируйте вашу модель Settings

# revision identifiers, used by Alembic.
revision = &amp;#x27;&amp;lt;revision_id&amp;gt;&amp;#x27;
down_revision = &amp;#x27;&amp;lt;previous_revision_id&amp;gt;&amp;#x27;
branch_labels = None
depends_on = None

def upgrade():
    # Получение текущей сессии
    bind = op.get_bind()
    session = Session(bind=bind)
    # Проверка существования таблицы (опционально)
    inspector = inspect(bind)
    if &amp;#x27;settings&amp;#x27; in inspector.get_table_names():
        # Вставка данных, если таблица существует
        settings = [
            Settings(key=&amp;#x27;is_mode_get_user_id&amp;#x27;, value=&amp;#x27;0&amp;#x27;),
            Settings(key=&amp;#x27;get_user_id_message&amp;#x27;, value=&amp;#x27;😶😶😶&amp;#x27;),
        ]
        for setting in settings:
            # Убедитесь, что данные добавляются только при отсутствии
            if not session.query(Settings).filter_by(key=setting.key).first():
                session.add(setting)
        session.commit()
        
def downgrade():
    # Откат: удаление данных
    bind = op.get_bind()
    session = Session(bind=bind)
        session.query(Settings).filter(
        Settings.key.in_([&amp;#x27;is_mode_get_user_id&amp;#x27;, &amp;#x27;get_user_id_message&amp;#x27;])
    ).delete(synchronize_session=False)
    session.commit()    &lt;/pre&gt;
  &lt;/section&gt;
  &lt;h4 id=&quot;SkRX&quot;&gt;Пояснения:&lt;/h4&gt;
  &lt;ol id=&quot;OUGR&quot;&gt;
    &lt;li id=&quot;cNKQ&quot;&gt;&lt;code&gt;Session(bind=bind)&lt;/code&gt;: Создаёт сессию на основе текущего соединения Alembic.&lt;/li&gt;
    &lt;li id=&quot;1Tx1&quot;&gt;Проверка на существование таблицы: Это полезно, если вы не уверены, что таблица уже создана.&lt;/li&gt;
    &lt;li id=&quot;GRyY&quot;&gt;Проверка существующих записей: Гарантирует, что данные не будут добавлены повторно, если миграция выполняется несколько раз.&lt;/li&gt;
  &lt;/ol&gt;
  &lt;h3 id=&quot;hIcX&quot;&gt;2. Внесение данных через ORM&lt;/h3&gt;
  &lt;p id=&quot;ht2r&quot;&gt;Этот метод подходит, если вы хотите вставить данные в таблицу в вашем основном коде приложения.&lt;/p&gt;
  &lt;h4 id=&quot;VkDg&quot;&gt;Пример:&lt;/h4&gt;
  &lt;section style=&quot;background-color:hsl(hsl(0,   0%,  var(--autocolor-background-lightness, 95%)), 85%, 85%);&quot;&gt;
    &lt;pre data-lang=&quot;python&quot; id=&quot;U0oS&quot;&gt;from sqlalchemy.orm import Session
from your_project.models import Settings
from sqlalchemy import create_engine
from your_project.database import Base  # где инициализируется ваш Base

# Создаём подключение к базе данных
engine = create_engine(&amp;quot;postgresql+psycopg2://username:password@localhost/dbname&amp;quot;)

def initialize_settings():
    with Session(engine) as session:
        # Добавляем данные, если они ещё не существуют
        if not session.query(Settings).filter_by(key=&amp;quot;is_mode_get_user_id&amp;quot;).first():
            session.add(Settings(key=&amp;quot;is_mode_get_user_id&amp;quot;, value=&amp;quot;0&amp;quot;))
        if not session.query(Settings).filter_by(key=&amp;quot;get_user_id_message&amp;quot;).first():
            session.add(Settings(key=&amp;quot;get_user_id_message&amp;quot;, value=&amp;quot;😶😶😶&amp;quot;))
        session.

# Вызываем функцию инициализации
if __name__ == &amp;quot;__main__&amp;quot;:
    initialize_settings()&lt;/pre&gt;
  &lt;/section&gt;
  &lt;h3 id=&quot;BAKm&quot;&gt;Что выбрать?&lt;/h3&gt;
  &lt;ul id=&quot;jpqe&quot;&gt;
    &lt;li id=&quot;H6xM&quot;&gt;Alembic миграции: Если данные должны быть добавлены вместе с обновлением структуры базы данных. Это лучший подход для контроля версий.&lt;/li&gt;
    &lt;li id=&quot;1X1j&quot;&gt;ORM: Если данные должны добавляться в рантайме, например, при первом запуске приложения.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;Xbaf&quot;&gt;Комбинированный подход:&lt;/h3&gt;
  &lt;p id=&quot;Ns95&quot;&gt;Если вы используете Alembic для структуры таблиц, но хотите более гибкий способ добавления данных, используйте Alembic с ORM в одном из миграционных скриптов, как показано в первом примере.&lt;/p&gt;
  &lt;p id=&quot;ZUNk&quot;&gt;&lt;/p&gt;
  &lt;tt-tags id=&quot;92YZ&quot;&gt;
    &lt;tt-tag name=&quot;chatgpt&quot;&gt;#chatgpt&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;python&quot;&gt;#python&lt;/tt-tag&gt;
    &lt;tt-tag name=&quot;alembic&quot;&gt;#alembic&lt;/tt-tag&gt;
  &lt;/tt-tags&gt;

</content></entry></feed>