Giter VIP home page Giter VIP logo

Comments (8)

idealism44 avatar idealism44 commented on July 30, 2024

Обязательно ли использование адаптеров Loader и Dumper?
В БД всё равно будут хранится только id целей: при загрузке отдаём id объектов, при выгрузке получаем id целей и при надобности образуем в Member или Channel.
И делать это не в адаптерах, а отдельными функциями до и после взаимодействия с БД. Чтобы этим не занимался psycopg.


Почитал документацию psycopg и я могу вынести предположение, как сделать это с помощью адаптеров:

В теме про конфигурации адаптации данных есть абзац:

By default, connections obtain an adapters map from the global map exposed as psycopg.adapters: changing the content of this object will affect every connection created afterwards. You may specify a different template adapters map using the context parameter on connect().

Говорят, мол, по умолчанию каждое соединение к БД берёт адаптеры из глобальной карты адаптеров в psycopg.adapters. Если хочется добавить свои глобально, то добавляйте адаптеры в psycopg.adapters: при каждом соединении будут ваши адаптеры. Если хотите адаптеры, зависящие от контекста, указывайте context при получении соединения БД connect().
Тип context при получении соединения это psycopg.adapt.AdaptersMap, который хранит в себе адаптеры для соединения. Именно его вы используете, чтобы добавить свои адаптеры.

Получается, при новом соединении к БД можно указать в качестве context эту карту адаптеров, которую мы создадим перед указанием context, и в неё будут добавлены адаптеры, преобразующие данные в зависимости от контекста. Но как сделать сами адаптеры преобразовывающими от контекста?
register_dumper() и register_loader() принимают только классы соответсвующих адаптеров: не получится сделать объект адаптера. И в этом адаптере должен быть ctx от бота, чтобы обрабатывать данные в зависимости от контекста.

Далее, моё предположение реализации:

Для динамического создания классов в Python есть функция type(). Её и буду использовать.
При вызове нового соединения в качестве context будем указывать вызов функции, который вернёт psycopg.adapt.AdaptersMap, в котором будут наши контекстные адаптеры. Для создания контекстных адаптеров буду преобразовывать текущие DiscordObjectsDumper и DiscordObjectsLoader в новый класс со своим атрибутом ctx.
В итоге получится что-то вроде такого:

class DiscordObjectsLoader:
    ctx = None

    def load(self, to_load):
        print("With context:", self.ctx)
        print("Loading:", to_load)


class DiscordObjectsDumper:
    ctx = None

    def dump(self, to_dump):
        print("With context:", self.ctx)
        print("Dumping:", to_dump)


def context_factory(ctx):
    return (
        type(
             'CtxDiscordObjectsLoader',
             (DiscordObjectsLoader,),
             {'ctx': ctx}
        ),
        type(
             'CtxDiscordObjectsDumper',
             (DiscordObjectsDumper,),
             {'ctx': ctx}
        )
    )


def context_adapters(ctx):
    adapters = []
    Loader, Dumper = context_factory(ctx)
    adapters.append(Loader)
    adapters.append(Dumper)
    return adapters
    

ctx = "my_ctx"

# with psycopg.connect(connection_string=..., context=context_adapters(ctx)):
# Load something
# Dump sometning
# hided
adapters = context_adapters(ctx)
Loader, Dumper = adapters
a = Loader()
a.load("foo")
b = Dumper()
b.dump("bar")
# hided

В зависимости от ctx будем получать разные сообщения:

With context: my_ctx
Loading: foo
With context: my_ctx
Dumping: bar

Так как вы используете только одно соединение, то можно адаптировать вариант под cursor: после создания курсора добавить в него адаптеры, так как он тоже поддерживает psycopg.adapt.AdaptersMap (почему).

Возможно я что-то упустил в документации, но мне больше нечего сказать.

from vtc-bot.

Debianov avatar Debianov commented on July 30, 2024

Довольно накладно выходит делать на каждый ctx по своему объекту. К сожалению, передать второй аргумент никак нельзя, передавать как-то кортежем через data вместе с основными данными к преобразованию не является нормой, поэтому решено убрать эти два класса из регистрации и вызывать их методы вручную.

from vtc-bot.

Debianov avatar Debianov commented on July 30, 2024

Убирать два этих класса тоже не вариант. Они нужны, иначе придётся прописывать обработку вручную во многих местах кода.

from vtc-bot.

Debianov avatar Debianov commented on July 30, 2024

Реализовано через Locator. commit

from vtc-bot.

idealism44 avatar idealism44 commented on July 30, 2024

То что вы реализовали - это глобальная переменная, ссылку на которую вы дали в классе адаптера Loader.
Так как бот асинхронный, то в момент выгрузки данных с ctx первого соединения может вмешаться второе, которое вставит своё ctx в Provider, и первое соединение теперь будет пользоваться ctx от второго соединения, что может послужить многим проблемам.

Убирать два этих класса тоже не вариант. Они нужны, иначе придётся прописывать обработку вручную во многих местах кода.

Можете рассказать, как вы взаимодействуете с полученными id объектов из БД? Зачем их превращать в Discord объекты?
Я не понимаю всей ситуации и предлагаю решения основываясь только на тексте из этого issue, из-за чего решения могут не подойти к настоящей обстановке.

from vtc-bot.

Debianov avatar Debianov commented on July 30, 2024

Так как бот асинхронный, то в момент выгрузки данных с ctx первого соединения может вмешаться второе, которое вставит своё ctx в Provider, и первое соединение теперь будет пользоваться ctx от второго соединения, что может послужить многим проблемам.

Да, я собираюсь делать словарь с извлечением контекста по объекту сообщения.

Можете рассказать, как вы взаимодействуете с полученными id объектов из БД? Зачем их превращать в Discord объекты?

Ну хотя бы взять извлечение объектов из БД по схожим критериям для поиска совпадений.

from vtc-bot.

idealism44 avatar idealism44 commented on July 30, 2024

Да, я собираюсь делать словарь с извлечением контекста по объекту сообщения.

Тогда можете, пожалуйста, это сделать? Или как-то покажите, что данная проблема ещё не решена, например оставить этот issue открытым. Ведь если всё так и оставить будут соответствующие проблемы.

Ну хотя бы взять извлечение объектов из БД по схожим критериям для поиска совпадений.

Классно придумано.

from vtc-bot.

Debianov avatar Debianov commented on July 30, 2024

оставить этот issue открытым

Понял

from vtc-bot.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.