Как мне сделать внутреннее соединение с внешним joiner на SQL в Python эффективным способом - PullRequest
0 голосов
/ 30 мая 2018

Я хочу объединить файл Excel с sql в pandas, вот мой код

import pandas as pd
import pymysql
from sqlalchemy import create_engine
data1 = pd.read_excel('data.xlsx')
engine = create_engine('...cloudprovider.com/...')
data2 = pd.read_sql_query("select id, column3, column4 from customer", engine)
data = data1.merge(data2, on='id', how='left')

Это работает, только чтобы сделать его более понятным

Если ввод data1.columns вывод Index(['id', 'column1', 'column2'], dtype='object')

Если вход data2.columns выход Index(['id', 'column3', 'column4'], dtype='object')

Если вход data.columns выход Index(['id', 'column1', 'column2', 'column3', 'column4'], dtype='object')

Поскольку data2 становится больше, я могу 't запрос полностью, поэтому я хочу запросить data2 с id, которые существуют на data1.Как я могу это сделать?

Ответы [ 2 ]

0 голосов
/ 30 мая 2018

Вы можете использовать тот факт, что SQLAlchemy является отличным построителем запросов.Либо отразите таблицу customer , либо создайте метаданные вручную:

from sqlalchemy import MetaData, select

metadata = MetaData()
metadata.reflect(engine, only=['customer'])
customer = metadata.tables['customer']

и создайте запрос , что позволяет SQLAlchemy беспокоиться о правильностииспользование заполнителей, преобразование данных и т. д. Вы ищете customer строк, где id находится в наборе идентификаторов из data1 , достигнутых в SQL с помощью оператора IN :

query = select([customer.c.id,
                customer.c.column3,
                customer.c.column4]).\
    where(customer.c.id.in_(data1['id']))

data2 = pd.read_sql_query(query, engine)

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

placeholders = ','.join(['%s'] * data1['id'].count())
# Note that you're not formatting the actual values here, but placeholders
query = f"SELECT id, column3, column4 FROM customer WHERE id IN ({placeholders})"
data2 = pd.read_sql_query(query, engine, params=data1['id'])

В целом, полезно научиться использовать заполнителивместо того, чтобы смешивать SQL и значения путем форматирования / объединения строк, так как это может подвергнуть вас внедрению SQL, если вы обрабатываете данные, созданные пользователем.Обычно вы бы указывали обязательные заполнители в строке запроса напрямую, но требуется некоторое строение строки, если у вас есть переменное количество параметров 1 .

1 :Некоторые драйверы DB-API, такие как psycopg2 , позволяют передавать кортежи и списки в виде скалярных значений и знают, как создать подходящий SQL.

0 голосов
/ 30 мая 2018

Поскольку вы просматриваете условие как WHERE IN [Some_List].Это должно работать для вас

id_list = data1['id'].tolist()
your_query = "select id, column3, column4 from customer where id in "+tuple(id_list)
data2 = pd.read_sql_query(your_query , engine)

Надеюсь, что это работает.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...