diff --git a/sqlite_utils/db.py b/sqlite_utils/db.py index 039f9da..fd58c40 100644 --- a/sqlite_utils/db.py +++ b/sqlite_utils/db.py @@ -2571,6 +2571,8 @@ class Table(Queryable): all_columns = [] first = True num_records_processed = 0 + # Fix up any records with square braces in the column names + records = fix_square_braces(records) # We can only handle a max of 999 variables in a SQL insert, so # we need to adjust the batch_size down if we have too many cols records = iter(records) @@ -2618,7 +2620,6 @@ class Table(Queryable): column for column in record if column not in all_columns ] - validate_column_names(all_columns) first = False self.insert_chunk( @@ -2986,3 +2987,14 @@ def validate_column_names(columns): assert ( "[" not in column and "]" not in column ), "'[' and ']' cannot be used in column names" + + +def fix_square_braces(records: Iterable[Dict[str, Any]]): + for record in records: + if any("[" in key or "]" in key for key in record.keys()): + yield { + key.replace("[", "_").replace("]", "_"): value + for key, value in record.items() + } + else: + yield record diff --git a/tests/test_create.py b/tests/test_create.py index c9568d9..187d20a 100644 --- a/tests/test_create.py +++ b/tests/test_create.py @@ -144,6 +144,7 @@ def test_create_table_with_not_null(fresh_db): [{"name": "memoryview", "type": "BLOB"}], ), ({"uuid": uuid.uuid4()}, [{"name": "uuid", "type": "TEXT"}]), + ({"foo[bar]": 1}, [{"name": "foo_bar_", "type": "INTEGER"}]), ), ) def test_create_table_from_example(fresh_db, example, expected_columns): @@ -525,13 +526,6 @@ def test_insert_row_alter_table( ] -def test_insert_row_alter_table_invalid_column_characters(fresh_db): - table = fresh_db["table"] - table.insert({"foo": "bar"}).last_pk - with pytest.raises(AssertionError): - table.insert({"foo": "baz", "new_col[abc]": 1.2}, alter=True) - - def test_add_missing_columns_case_insensitive(fresh_db): table = fresh_db["foo"] table.insert({"id": 1, "name": "Cleo"}, pk="id")