как вернуть некоторое значение по умолчанию для элементов в предложении 'where', которые не совпадают (не существуют) в столбце таблицы базы данных - PullRequest
0 голосов
/ 26 октября 2018

У меня есть таблица базы данных flight

pkid       from_city            to_city
1         Melbourne            BuenosAires
2         Budapest             Tokyo
3         Praslin              Anchorage

Тогда у меня есть список / кортеж некоторых случайных to_cities ['Paris','Tokyo','Madrid','Anchorage','im_not_on_earth']

Теперь, используя метаданные sqlalchemy, я хочу запрос, который возвратил бы pkid для соответствующего to_city в данном списке, если он существует, или возвращает какое-то значение по умолчанию, скажем 0, если не существует

Так что в основном мои выходные данные должны давать мне определенное целое число для каждого города, где я могу сопоставить каждое целое число в своем выходном сигнале с каким-либо городом в данном входном сигнале

Любые примеры вывода, приведенные ниже, будут работать для меня -

{'Paris':0, 'Tokyo': 2, 'Madrid': 0, 'Anchorage': 3, 'im_not_on_earth': 0}

или просто ...... [0,2,0,3,0]

Есть идеи или предложения как это сделать? Я думал, что смогу достичь этого, используя коалесцию. Но это работает, только если значения в предложении where существуют в таблице базы данных. Не уверен, правильно ли я понимаю слияние.

EDIT: ** Я не хочу повторять использование цикла for и запроса для каждого элемента в заданном вводе **

Ответы [ 2 ]

0 голосов
/ 27 октября 2018

То, что вы хотите сделать, - внешнее соединение между предоставленным списком городов и столбцом to_city в таблице полетов. Учитывая, что в базе данных нет сведений о вашем списке предоставленных городов, вам придется выполнить это объединение в коде приложения с циклом. В вашем примере кода вы также видите, что каждый to_city отображается только в одной строке базы данных и, следовательно, отображается только в один pkid. Я предполагаю, что для нескольких разных from_cities будет возможно, чтобы полеты выполнялись в одном и том же to_city, и поэтому вам нужно будет сопоставлять каждый to_city списку pkids, а не одному значению. Следовательно, to_city, на который не выполняются рейсы, будет представлен пустым списком, а не 0.

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

from collections import defaultdict

class Flight(Base):
    __tablename__ = 'flight'

    pkid = Column(Integer, primary_key=True)
    from_city = Column(String)
    to_city = Column(String)

to_cities = ['Paris','Tokyo','Madrid','Anchorage','im_not_on_earth']
query_result = session.query(Flight.to_city, Flight.pkid).filter(Flight.to_city.in_(to_cities)).all()
matching_cities = defaultdict(list)
for city, pkid in query_result:
    matching_cities[city] += [pkid]
result = {city: matching_cities.get(city, []) for city in to_cities}

Стоит подумать о дизайне вашей базы данных, учитывая, что вам приходится выполнять внешнее соединение в коде приложения. База данных будет гораздо более эффективным местом для этого. Если бы у вас была отдельная таблица всех названий городов с отношением внешнего ключа к таблице полетов, вы могли бы достичь того, что вы хотите, в одном запросе, выполнив внешнее соединение между таблицами городов и полетов в вашем запросе.

0 голосов
/ 26 октября 2018

Вы можете использовать apply() и определить свою собственную функцию, например:

def get_id(x):

    find = flight[flight['to_city']==x]['pkid'].values
    match = find[0] if list(find) else 0
    return match

dict(zip(to_cities, pd.Series(to_cities).apply(get_id).values))

Выход:

{'Paris': 0, 'Tokyo': 2, 'Madrid': 0, 'Anchorage': 3, 'im_not_on_earth': 0}
...