Как получить что-то вроде fast_executemany с SQLAlchemy 1.3.18 с Sybase, чтобы повысить скорость вставки в? - PullRequest
1 голос
/ 07 августа 2020

Я сделал программу для вставки в базу данных Sybase в Python, я использую pandas 1.0.4 и SQLAlchemy 1.3.18.

Я установил связь между sybase и моим script, но на самом деле скорость вставки в таблицы действительно очень медленная (10 минут для 30k строк ...)

На SQL Server с тем же кодом (за исключением параметра fast_executemany = True в create_engine, и параметры method = 'multi', chunksize = 500 для dataframe.to_ sql ()), я сделал вставку в 3 секунды.

Есть ли у вас идея исправить это?

Хорошего дня!

Ответы [ 2 ]

2 голосов
/ 10 августа 2020

Внешний диалект SAP ASE (Sybase) поддерживает fast_executemany, если вы используете драйвер SAP ASE ODB C.

1 голос
/ 10 августа 2020

Похоже, что Sybase ASE не поддерживает предложение VALUES с несколькими значениями в INSERT. Вы можете сформировать UNION из SELECT операторов, если вам нужно вставить несколько значений в один оператор вместо , используя executemany, чтобы просто выдать множество операторов INSERT:

from sqlalchemy import union_all, select, literal

def sybase_insert(sqltable, conn, keys, data_iter):
    sel = union_all(*[select([literal(v) for v in row]) for row in data_iter])
    ins = sqltable.table.insert().from_select(keys, sel)
    conn.execute(ins)

Передайте функцию как method при вызове to_sql():

In [11]: pd.DataFrame({"A": range(3)}).to_sql("foo", con=engine, method=sybase_insert)
2020-08-10 08:29:44,474 INFO sqlalchemy.engine.base.Engine PRAGMA main.table_info("foo")
2020-08-10 08:29:44,474 INFO sqlalchemy.engine.base.Engine ()
2020-08-10 08:29:44,475 INFO sqlalchemy.engine.base.Engine PRAGMA temp.table_info("foo")
2020-08-10 08:29:44,475 INFO sqlalchemy.engine.base.Engine ()
2020-08-10 08:29:44,477 INFO sqlalchemy.engine.base.Engine 
CREATE TABLE foo (
        "index" BIGINT, 
        "A" BIGINT
)


2020-08-10 08:29:44,477 INFO sqlalchemy.engine.base.Engine ()
2020-08-10 08:29:44,477 INFO sqlalchemy.engine.base.Engine COMMIT
2020-08-10 08:29:44,478 INFO sqlalchemy.engine.base.Engine CREATE INDEX ix_foo_index ON foo ("index")
2020-08-10 08:29:44,478 INFO sqlalchemy.engine.base.Engine ()
2020-08-10 08:29:44,478 INFO sqlalchemy.engine.base.Engine COMMIT
2020-08-10 08:29:44,479 INFO sqlalchemy.engine.base.Engine BEGIN (implicit)
2020-08-10 08:29:44,481 INFO sqlalchemy.engine.base.Engine INSERT INTO foo ("index", "A") SELECT ? AS anon_1, ? AS anon_2 UNION ALL SELECT ? AS anon_3, ? AS anon_4 UNION ALL SELECT ? AS anon_5, ? AS anon_6
2020-08-10 08:29:44,481 INFO sqlalchemy.engine.base.Engine (0, 0, 1, 1, 2, 2)
2020-08-10 08:29:44,481 INFO sqlalchemy.engine.base.Engine COMMIT
...