SQLAlchemy session.query (Table) команда слишком медленная. Что не так с моим кодом? - PullRequest
0 голосов
/ 27 апреля 2018

Попробуйте выбрать все строки в таблице базы данных с примерно 300 000 строк

(Tablename = 'test_table', я использую Aurora Mysql)

from sqlalchemy.engine import create_engine, url
from sqlalchemy.orm import Session, sessionmaker

# Create a connection pool and get a session object as a property.
class Pool(object):

    def __init__(self, database, database_config):
        self.database_config = self.set_config_with_database_name(
            database, database_config)
        self.url_ = url.URL(**self.database_config)
        self.engine = create_engine(
            self.url_, echo=True, echo_pool=True, pool_size=2, max_overflow=5)
        self.Session_ = sessionmaker(bind=self.engine)

    @property
    def session(self) -> Session:
        return self.Session_()

    def set_config_with_database_name(self, database, database_config):
        conf_with_database = database_config.copy()
        conf_with_database['database'] = database
        return conf_with_database

И я пытаюсь получить доступ к таблице через сеанс для получения данных.

# Table class generated by sqlacodegen
from models import TestTable 

# config helper
config = get_config('./config/database.ini', 'backend') 

# get a session from Pool class
connection_pool = Pool('test', config) 
session = connection_pool.session

# It takes an long time in this part.
result = session.query(TestTable.id, TestTable.name).filter(
TestTable.is_use.is_(True)).all()

Ниже приведен журнал эха sqlalchemy.

2018-04-27 15:03:10,932 INFO sqlalchemy.engine.base.Engine SHOW VARIABLES LIKE 'sql_mode'
2018-04-27 15:03:10,933 INFO sqlalchemy.engine.base.Engine {}
2018-04-27 15:03:11,017 INFO sqlalchemy.engine.base.Engine SELECT DATABASE()
2018-04-27 15:03:11,018 INFO sqlalchemy.engine.base.Engine {}
2018-04-27 15:03:11,095 INFO sqlalchemy.engine.base.Engine show collation where `Charset` = 'utf8' and `Collation` = 'utf8_bin'
2018-04-27 15:03:11,096 INFO sqlalchemy.engine.base.Engine {}
2018-04-27 15:03:11,143 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS CHAR(60)) AS anon_1
2018-04-27 15:03:11,144 INFO sqlalchemy.engine.base.Engine {}
2018-04-27 15:03:11,191 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS CHAR(60)) AS anon_1
2018-04-27 15:03:11,194 INFO sqlalchemy.engine.base.Engine {}
2018-04-27 15:03:11,236 INFO sqlalchemy.engine.base.Engine SELECT CAST('test collated returns' AS CHAR CHARACTER SET utf8) COLLATE utf8_bin AS anon_1
2018-04-27 15:03:11,237 INFO sqlalchemy.engine.base.Engine {}
2018-04-27 15:03:11,319 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2018-04-27 15:03:11,323 INFO sqlalchemy.engine.base.Engine SELECT test_table.id AS test_table_id, test_table.name AS test_table_name FROM test_table WHERE test_table.is_use IS true
2018-04-27 15:03:11,324 INFO sqlalchemy.engine.base.Engine {} // stucked here

Если честно, я не чувствую, в чем проблема. Пожалуйста, дайте мне знать, какую часть я пропускаю

1 Ответ

0 голосов
/ 28 апреля 2018

Наконец-то я понял, в чем проблема. Это потому, что я выполнил запрос на выборку, чтобы получить слишком много данных за раз.

Я решил проблему с помощью sqlalchemy.orm.query.Query. yield_per

Ниже приведен код для сравнения yield_per с и без yield_per

# Assume that there are about 600,000 rows in the TestTable

rows = session.query(TestTable).filter(TestTable.is_use.is_(True))
yield_rows = session.query(TestTable).filter(TestTable.is_use.is_(True)).yield_per(200)

@timer
def print_rows(result_rows):
    for row in result_rows:
        if row.id > 300: # print only 300 rows
            break

print_rows(rows) # Elapsed: 21.57
print_rows(yield_rows) # Elapsed: 0.68

Если у вас есть какой-нибудь другой способ, пожалуйста, прокомментируйте или ответьте!

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