Запрос индекса с использованием ‘pd.read_sql_query’ приводит к «OperationalError: (sqlite3.OperationalError) рядом с «index»: синтаксическая ошибка»

#python #sql #pandas #sqlalchemy

#python #sql #pandas #sqlalchemy

Вопрос:

У меня есть очень большой файл фрейма данных, который не может быть полностью загружен в память, и мне нужно получить много строк по индексу, и эти строки не являются последовательными, поэтому использование pandas.read_csv с пропуском строк и nrows не показалось эффективным способом извлечения этих строк.

Я увидел, что в моем случае база данных, вероятно, является лучшим способом обработки моих данных.

Мне удалось отправить свои данные в базу данных sql, но я получаю ошибку при попытке извлечения по индексу.

Ниже приведен минимальный пример

 import pandas as pd
import numpy as np
from sqlalchemy import create_engine

engine = create_engine('sqlite:///memory.db')

data = pd.DataFrame(np.random.randint(0,100,size=(15, 4)), columns=list('ABCD'))

data.head(2)


A   B   C   D
0   64  57  97  99
1   58  31  32  43
  

Я попробовал несколько запросов, которые отлично сработали

 pd.read_sql_query('SELECT * FROM data', engine)


index   A   B   C   D
0   0   64  57  97  99
1   1   58  31  32  43
2   2   89  56  76  53
3   3   68  13  20  39
4   4   84  34  25  12
5   5   58  10  46  37
6   6   50  85  96  68
7   7   41  55  88  92
8   8   54  72  49  56
9   9   58  20  15  92
10  10  92  20  11  81
11  11  88  6   81  1
12  12  90  90  39  11
13  13  64  84  37  80
14  14  8   82  90  22
  

Одна вещь, которую я заметил, что исходный индекс устанавливается в отдельный столбец. Я прочитал документацию в to_sql, но я не смог найти ничего, что устанавливало бы для индекса pandas df значение индекса thq sql, там написано «indexbool, значение по умолчанию True
Запишите индекс фрейма данных в виде столбца. Использует index_label в качестве имени столбца в таблице». но, похоже, это означает, что если для него не установлено значение true, индекс не будет передан в базу данных.

Запрос по столбцам, похоже, работает нормально

 pd.read_sql_query('SELECT A, C FROM data', engine)


A   C
0   64  97
1   58  32
2   89  76
3   68  20
4   84  25
5   58  46
6   50  96
7   41  88
8   54  49
9   58  15
10  92  11
11  88  81
12  90  39
13  64  37
14  8   90


pd.read_sql_query('SELECT A, C FROM data WHERE B=57', engine)

    A   C
0   64  97
  

Но выбор из столбца индекса приводит к ошибке

 pd.read_sql_query('SELECT A FROM data WHERE index=2', engine)



---------------------------------------------------------------------------
OperationalError                          Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/base.py in _execute_context(self, dialect, constructor, statement, parameters, *args)
   1277                     self.dialect.do_execute(
-> 1278                         cursor, statement, parameters, context
   1279                     )

12 frames
OperationalError: near "index": syntax error

The above exception was the direct cause of the following exception:

OperationalError                          Traceback (most recent call last)
/usr/local/lib/python3.6/dist-packages/sqlalchemy/engine/default.py in do_execute(self, cursor, statement, parameters, context)
    591 
    592     def do_execute(self, cursor, statement, parameters, context=None):
--> 593         cursor.execute(statement, parameters)
    594 
    595     def do_execute_no_params(self, cursor, statement, context=None):

OperationalError: (sqlite3.OperationalError) near "index": syntax error
[SQL: SELECT A FROM data WHERE index=2;]
(Background on this error at: http://sqlalche.me/e/13/e3q8)
  

Комментарии:

1. Индекс — это ключевое слово, если вы хотите сослаться на столбец, вы должны использовать идентификатор, заключенный в кавычки "index" .

2. Вау, спасибо! Существует ли философия проектирования sql для помещения индекса в кавычки?

3. SQL имеет обычные идентификаторы с разделителями (в кавычках) и ключевые слова. Существуют незащищенные и зарезервированные ключевые слова. В индексе SQLite есть зарезервированное ключевое слово: sqlite.org/lang_keywords.html , поэтому вы не можете использовать его в качестве обычного идентификатора.

4. Добавляя к предыдущему, не зарезервированные ключевые слова являются ключевыми словами в некоторых контекстах, но не в других, поэтому они могут использоваться как обычные идентификаторы в некоторых контекстах.