(2) в основном реализовано как (1), и оба могут выдавать 50 000 вставок во время сброса, если ORM должен извлечь сгенерированные значения, такие как первичные ключи. Они могут даже испускать больше, если эти 50 000 объектов имеют каскадные отношения.
In [4]: session.add_all([Foo() for _ in range(5)])
In [5]: session.commit()
BEGIN (implicit)
INSERT INTO foo DEFAULT VALUES RETURNING foo.id
{}
... (repeats 3 times)
INSERT INTO foo DEFAULT VALUES RETURNING foo.id
{}
COMMIT
Если вы заранее предоставите первичные ключи и другие значения, сгенерированные БД, тогда Session
может объединять отдельные вставки в одно "executemany""операция, когда аргументы совпадают.
In [8]: session.add_all([Foo(id=i) for i in range(5)])
In [9]: session.commit()
BEGIN (implicit)
INSERT INTO foo (id) VALUES (%(id)s)
({'id': 0}, {'id': 1}, {'id': 2}, {'id': 3}, {'id': 4})
COMMIT
Если ваш драйвер DB-API реализует executemany()
или эквивалент , используя метод, который позволяет ему выпустить одиноператор с несколькими данными, то это может привести к одному запросу. Например, после включения executemany_mode='values'
журнал Postgresql содержит для вышеупомянутого
LOG: statement: INSERT INTO foo (id) VALUES (0),(1),(2),(3),(4)
Массовая операция пропускает большую часть механизма Session
- такого как сохраняющиеся связанные объекты - в обмен наприрост производительности. Например, по умолчанию он не извлекает значения по умолчанию, такие как первичные ключи, что позволяет ему попытаться выполнить пакетные изменения с меньшим количеством операций executemany, в которых совпадают операция и аргументы.
In [12]: session.bulk_save_objects([Foo() for _ in range(5)])
BEGIN (implicit)
INSERT INTO foo DEFAULT VALUES
({}, {}, {}, {}, {})
In [13]: session.commit()
COMMIT
Может по-прежнему выдаватьнесколько операторов, опять же в зависимости от данных и используемого драйвера DB-API. Документация - хорошее чтение.
С включенными помощниками по быстрому исполнению psycopg2 вышеупомянутые результаты в журнале Postgresql
LOG: statement: INSERT INTO foo DEFAULT VALUES;INSERT INTO foo DEFAULT VALUES;INSERT INTO foo DEFAULT VALUES;INSERT INTO foo DEFAULT VALUES;INSERT INTO foo DEFAULT VALUES
Другими словаминесколько операторов были объединены в один оператор, отправляемый на сервер.
Итак, в конечном итоге ответ на все три вопроса - «это зависит», что, конечно, может показаться разочаровывающим.