Skip to content

Claude/mysql bulk load - #6

Closed
martinv13 wants to merge 6 commits into
mainfrom
claude/mysql-bulk-load
Closed

Claude/mysql bulk load#6
martinv13 wants to merge 6 commits into
mainfrom
claude/mysql-bulk-load

Conversation

@martinv13

Copy link
Copy Markdown
Owner

No description provided.

claude added 6 commits June 20, 2026 10:04
Implements MySQLDialect.bulk_insert() using MySQL's LOAD DATA LOCAL INFILE
for pymysql and mysqldb drivers. Binary columns are hex-encoded in the temp
file and decoded server-side with UNHEX(). Falls back to SQLAlchemy
executemany for unsupported drivers. Adds integration tests and updates the
MySQL CI workflow to enable local_infile on the server.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvgSwLLGgKaDbZaEYYp7BJ
- Move engine creation into each dialect (create_engine() override) so
  MySQL can inject local_infile=True and MSSQL can inject fast_executemany
  and SERIALIZABLE isolation level automatically when a connection string is
  provided via DataModel.
- Add bulk_load (bool | None) and bulk_load_threshold (int | None) keyword
  arguments to Document.insert_into_target_tables() and bulk_insert() on
  all dialects. None (default) = use bulk loading when available with silent
  fallback; True = require it and raise RuntimeError with an actionable
  message if unavailable; False = always use executemany.
- Remove use_bcp parameter (never publicly released).
- Default thresholds: 100 rows for MySQL / MSSQL / DuckDB (file-based),
  0 for PostgreSQL (in-protocol COPY, no temp file).
- Add corresponding tests for bulk_load=True/False/RuntimeError paths on
  MySQL and MSSQL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvgSwLLGgKaDbZaEYYp7BJ
Add a "Bulk loading" subsection to how_it_works.md explaining the native
bulk-loading mechanism used by each backend (COPY, LOAD DATA LOCAL INFILE,
BCP, read_csv), the required drivers/tools, the default per-dialect row
threshold, and how the new bulk_load / bulk_load_threshold parameters on
Document.insert_into_target_tables() control the behaviour.

Expand the driver lists in index.md, getting_started.md, and README.md to
include psycopg (psycopg3) alongside psycopg2 for PostgreSQL, and
mysqlclient alongside pymysql for MySQL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvgSwLLGgKaDbZaEYYp7BJ
Swap "value — description" patterns for "value to/: description" phrasing
throughout dialect and document docstrings.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvgSwLLGgKaDbZaEYYp7BJ
test_mysql_bulk_insert_numeric_types uses a table with only i/bi/si/d
columns; order_by(table.c.id) raised AttributeError. Apply ordering
only when the id column is present.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvgSwLLGgKaDbZaEYYp7BJ
Parametrized over [10, 50, 100, 500, 5000] rows so the read_csv vs
executemany crossover relative to _READ_CSV_THRESHOLD (100) is visible.
Excluded from normal CI via addopts in pyproject.toml; run manually
with: pytest -m benchmark -s -v

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QvgSwLLGgKaDbZaEYYp7BJ
@martinv13 martinv13 closed this Jun 20, 2026
@martinv13
martinv13 deleted the claude/mysql-bulk-load branch June 20, 2026 21:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants