Nano Hash - криптовалюты, майнинг, программирование

Как в sqlalchemy получить запрос, который соответствует всем строкам в таблице, чтобы ни одна строка в другой таблице не ссылалась на него?

У меня есть две таблицы: «событие» и «event_exception». В таблице «event» есть (логический) столбец «regular», который указывает, должно ли событие происходить регулярно каждый год или нет. В таблице «event_exception» есть столбец «event_id», столбец «год» и столбец (логический) «происходит».

Данные следует интерпретировать следующим образом:

  • Некоторые события происходят регулярно каждый год, но иногда они не происходят в исключительных случаях, что кодируется строкой «event» с «event.regular == True» и строкой «event_exception» с «event_exception.occurs == False» для каждый год, когда это событие в исключительных случаях не проводится.
  • Некоторые события происходят нерегулярно, но иногда случаются в исключительных случаях. Это кодируется строкой «event» с «event.regular == False» и строкой «event_exception» с «event_exception.occurs == True» для каждого года, когда событие происходит исключительно.

Как написать запрос, соответствующий всем событиям, которые произойдут в этом году?

Мое предположение было чем-то вроде

session.query(Event, EventException).filter(Event.id==EventException.event_id)
.filter(EventException.year==current_year).
filter(or_(
    and_(Event.regular==1, EventException.occurs==0, having(count(EventException)==0)),
    and_(Event.regular==0, EventException==1, having(count(EventException)>0)
))

, но я не уверен, что предложение having можно использовать в and_.

02.09.2012

Ответы:


1

Вы не можете использовать HAVING без GROUP BY. В любом случае, ни один из них в данном случае не нужен, нужен EXISTS. Предполагая, что у вас уже есть связь SQLAlchemy, определенная для Event.exceptions, должно работать следующее выражение:

session.query(Event).filter(or_(
    and_(
        Event.regular == True,
        ~Event.exceptions.any(and_(
            EventException.year == current_year,
            EventException.occurs == False,
        )),
    ),
    and_(
        Event.regular == False,
        Event.exceptions.any(and_(
            EventException.year == current_year,
            EventException.occurs == True,
        )),
    ),
))

и сгенерируйте SQL следующим образом:

SELECT event.*
FROM event
WHERE
    (
        event.regular = true
        AND NOT EXISTS (
            SELECT 1
            FROM event_exception
            WHERE
                event.id = event_exception.event_id
                AND event_exception.year == :year
                AND event_exception.occurs = false
        )
    )
    OR
    (
        event.regular = false
        AND EXISTS (
            SELECT 1
            FROM event_exception
            WHERE
                event.id = event_exception.event_id
                AND event_exception.year == :year
                AND event_exception.occurs = true
        )
    )

РЕДАКТИРОВАТЬ: вместо первого условия следует использовать NOT EXISTS

03.09.2012
  • У меня все еще не было времени попробовать, но ваше решение звучит очень логично. 14.09.2012

  • 2

    Не уверен в ответе, я просто хотел отметить несколько вещей, поскольку недавно у меня были проблемы с логическими запросами в sqlalchemy...

    • Вы должны делать логические сравнения как '== True' и '== False'. MySQL хранит Boolean как 1/0, но PostgreSQL и другие хранят как true/false, как и Python. SqlAlchemy преобразует по мере необходимости, но когда вы смотрите на чужой код... это выглядит как сравнение INT, а не BOOL. Просто другим людям, которым придется смотреть на это в будущем, будет проще. .

    • В зависимости от механизма хранения SQL и значений столбца по умолчанию вы можете не получить желаемых результатов. Если в наборе разрешены значения NULL, ваши сравнения не будут совпадать. Вы получите нужные результаты с помощью поиска, например:

      Event.regular.op('IS NOT')(True)

      Event.regular.op('IS')(False)

      sqlalchemy.sql.functions.coalesce( Event.regular , False ) != True sqlalchemy.sql.functions.coalesce( Event.regular , False ) == False

    В первом фрагменте кода мы ищем элементы, которые не являются True, что может быть одновременно False и NULL. Набор результатов для regular != True содержит только False элементов; набор результатов для regular IS NOT True содержит False и Null

    Во втором фрагменте кода база данных будет объединять Null значений в False перед сравнением.

    Возможно, вам не нужно проводить эти сравнения, но если вы это сделаете, и ваши результаты не будут выглядеть правильно, возможно, поэтому.

    02.09.2012
  • Я очень рад, что кто-то дал ответ, чтобы указать разницу между IS и ==. Это решает мою загадку. Спасибо! 10.07.2015
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..