Ваша ошибка в использовании интерполяции строк:
sql = ('SELECT lat, long FROM airportCoords WHERE iata IN %s' %(origin))
Поскольку origin
является массивом Numpy, это приводит к синтаксису [....]
идентификатора SQL в запросе;см. документацию по SQLite :
Если вы хотите использовать ключевое слово в качестве имени, вам нужно заключить его в кавычки.Существует четыре способа цитирования ключевых слов в SQLite:
[...]
[keyword]
Ключевое слово, заключенное в квадратные скобки, является идентификатором.[...]
Вы попросили SQLite проверить, находится ли iata
в таблице с именем ['JFK' 'JFK' 'JFK' ... 'MIA' 'JFK' 'MIA']
, потому что это строковое представление массива Numpy.
Вы ужеиспользуя SQLAlchemy, было бы проще, если бы вы использовали эту библиотеку для генерации всего SQL для вас, включая тест членства IN (....)
:
from sqlalchemy import *
filter = literal_column('iata', String).in_(origin)
sql = select([
literal_column('lat', Float),
literal_column('long', Float),
]).select_from(table('airportCoords')).where(filter)
и затем sql
в качестве запроса.
Я использовал здесь literal_column()
и table()
объекты для быстрого доступа к именам объектов, но вы также можете попросить SQLAlchemy отразить вашу таблицу базы данных непосредственно из объекта engine
, который вы уже создализатем используйте полученное определение таблицы, чтобы сгенерировать запрос:
metadata = MetaData()
airport_coords = Table('airportCoords', metadata, autoload=True, autoload_with=engine)
, в этот момент запрос будет определен как:
filter = airport_coords.c.iata.in_(origin)
sql = select([airport_coords.c.lat, airport_coords.c.long]).where(filter)
Я бы также включил код iata
в выходных данных, в противном случае у вас не будет пути к подключению кода IATA к соответствующим координатам:
sql = select([airport_coords.c.lat, airport_coords.c.long, airport_coords.c.iata]).where(filter)
Далее, как вы говорите, в списке 604 885 элементов, поэтому вы , вероятно, хочу загрузить данные CSVa во временную таблицу для обеспечения эффективности запроса:
engine = create_engine('sqlite:///airport_coordinates.db')
# code to read CSV file
# ...
df_airports = pd.read_csv(temp_file, usecols=fields)
# SQLAlchemy table wrangling
metadata = MetaData()
airport_coords = Table('airportCoords', metadata, autoload=True, autoload_with=engine)
temp = Table(
"airports_temp",
metadata,
*(Column(field, String) for field in fields),
prefixes=['TEMPORARY']
)
with engine.begin() as conn:
# insert CSV values into a temporary table in SQLite
temp.create(conn, checkfirst=True)
df_airports.to_sql(temp.name), engine, if_exists='append')
# Join the airport coords against the temporary table
joined = airport_coords.join(temp, airport_coords.c.iata==temp.c.Origin_Airport_Code)
# select coordinates per airport, include the iata code
sql = select([airport_coords.c.lat, airport_coords.c.long, airport_coords.c.iata]).select_from(joined)
df_origin = pd.read_sql(sql, engine)