#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. Добавляя к предыдущему, не зарезервированные ключевые слова являются ключевыми словами в некоторых контекстах, но не в других, поэтому они могут использоваться как обычные идентификаторы в некоторых контекстах.