commitdb 1.6.0__tar.gz → 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {commitdb-1.6.0 → commitdb-2.0.0}/PKG-INFO +30 -2
- {commitdb-1.6.0 → commitdb-2.0.0}/README.md +29 -1
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb/lib/libcommitdb-linux-amd64.so +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb.egg-info/PKG-INFO +30 -2
- {commitdb-1.6.0 → commitdb-2.0.0}/pyproject.toml +1 -1
- {commitdb-1.6.0 → commitdb-2.0.0}/tests/test_client.py +196 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb/__init__.py +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb/binding.py +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb/client.py +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb.egg-info/SOURCES.txt +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb.egg-info/dependency_links.txt +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb.egg-info/requires.txt +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/commitdb.egg-info/top_level.txt +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/setup.cfg +0 -0
- {commitdb-1.6.0 → commitdb-2.0.0}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: commitdb
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Python driver for CommitDB SQL Server
|
|
5
5
|
Author: CommitDB Contributors
|
|
6
6
|
License: Apache-2.0
|
|
@@ -62,6 +62,9 @@ with CommitDB('localhost', 3306) as db:
|
|
|
62
62
|
# Insert data
|
|
63
63
|
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')")
|
|
64
64
|
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (2, 'Bob', 'bob@example.com')")
|
|
65
|
+
|
|
66
|
+
# Bulk insert (multiple rows in one statement)
|
|
67
|
+
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (3, 'Charlie', 'c@example.com'), (4, 'Diana', 'd@example.com')")
|
|
65
68
|
|
|
66
69
|
# Query data - returns iterable of dictionaries
|
|
67
70
|
result = db.query('SELECT * FROM mydb.users')
|
|
@@ -70,7 +73,32 @@ with CommitDB('localhost', 3306) as db:
|
|
|
70
73
|
print(f" {row['id']}: {row['name']} ({row['email']})")
|
|
71
74
|
|
|
72
75
|
# Use convenience methods
|
|
73
|
-
db.insert('mydb', 'users', ['id', 'name', 'email'], [
|
|
76
|
+
db.insert('mydb', 'users', ['id', 'name', 'email'], [5, 'Eve', 'eve@example.com'])
|
|
77
|
+
|
|
78
|
+
# Use IN operator for multiple values
|
|
79
|
+
result = db.query("SELECT * FROM mydb.users WHERE id IN (1, 3)")
|
|
80
|
+
|
|
81
|
+
# Modify table schema
|
|
82
|
+
db.execute('ALTER TABLE mydb.users ADD COLUMN phone STRING')
|
|
83
|
+
db.execute('ALTER TABLE mydb.users RENAME COLUMN phone TO mobile')
|
|
84
|
+
db.execute('ALTER TABLE mydb.users DROP COLUMN mobile')
|
|
85
|
+
|
|
86
|
+
# Use string functions
|
|
87
|
+
result = db.query('SELECT UPPER(name) AS upper_name FROM mydb.users')
|
|
88
|
+
result = db.query("SELECT CONCAT(name, '@example.com') AS email FROM mydb.users")
|
|
89
|
+
|
|
90
|
+
# Use date functions
|
|
91
|
+
result = db.query('SELECT NOW() FROM mydb.users')
|
|
92
|
+
result = db.query("SELECT YEAR(created_at), MONTH(created_at) FROM mydb.events")
|
|
93
|
+
|
|
94
|
+
# Use JSON columns and functions
|
|
95
|
+
db.execute("CREATE TABLE mydb.docs (id INT PRIMARY KEY, data JSON)")
|
|
96
|
+
db.execute("INSERT INTO mydb.docs (id, data) VALUES (1, '{\"name\":\"Alice\"}')")
|
|
97
|
+
result = db.query("SELECT JSON_EXTRACT(data, '$.name') FROM mydb.docs")
|
|
98
|
+
|
|
99
|
+
# Bulk CSV import/export with COPY INTO
|
|
100
|
+
db.execute("COPY INTO '/tmp/users.csv' FROM mydb.users") # Export
|
|
101
|
+
db.execute("COPY INTO mydb.users FROM '/tmp/users.csv'") # Import
|
|
74
102
|
```
|
|
75
103
|
|
|
76
104
|
### Embedded Mode (no server required)
|
|
@@ -40,6 +40,9 @@ with CommitDB('localhost', 3306) as db:
|
|
|
40
40
|
# Insert data
|
|
41
41
|
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')")
|
|
42
42
|
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (2, 'Bob', 'bob@example.com')")
|
|
43
|
+
|
|
44
|
+
# Bulk insert (multiple rows in one statement)
|
|
45
|
+
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (3, 'Charlie', 'c@example.com'), (4, 'Diana', 'd@example.com')")
|
|
43
46
|
|
|
44
47
|
# Query data - returns iterable of dictionaries
|
|
45
48
|
result = db.query('SELECT * FROM mydb.users')
|
|
@@ -48,7 +51,32 @@ with CommitDB('localhost', 3306) as db:
|
|
|
48
51
|
print(f" {row['id']}: {row['name']} ({row['email']})")
|
|
49
52
|
|
|
50
53
|
# Use convenience methods
|
|
51
|
-
db.insert('mydb', 'users', ['id', 'name', 'email'], [
|
|
54
|
+
db.insert('mydb', 'users', ['id', 'name', 'email'], [5, 'Eve', 'eve@example.com'])
|
|
55
|
+
|
|
56
|
+
# Use IN operator for multiple values
|
|
57
|
+
result = db.query("SELECT * FROM mydb.users WHERE id IN (1, 3)")
|
|
58
|
+
|
|
59
|
+
# Modify table schema
|
|
60
|
+
db.execute('ALTER TABLE mydb.users ADD COLUMN phone STRING')
|
|
61
|
+
db.execute('ALTER TABLE mydb.users RENAME COLUMN phone TO mobile')
|
|
62
|
+
db.execute('ALTER TABLE mydb.users DROP COLUMN mobile')
|
|
63
|
+
|
|
64
|
+
# Use string functions
|
|
65
|
+
result = db.query('SELECT UPPER(name) AS upper_name FROM mydb.users')
|
|
66
|
+
result = db.query("SELECT CONCAT(name, '@example.com') AS email FROM mydb.users")
|
|
67
|
+
|
|
68
|
+
# Use date functions
|
|
69
|
+
result = db.query('SELECT NOW() FROM mydb.users')
|
|
70
|
+
result = db.query("SELECT YEAR(created_at), MONTH(created_at) FROM mydb.events")
|
|
71
|
+
|
|
72
|
+
# Use JSON columns and functions
|
|
73
|
+
db.execute("CREATE TABLE mydb.docs (id INT PRIMARY KEY, data JSON)")
|
|
74
|
+
db.execute("INSERT INTO mydb.docs (id, data) VALUES (1, '{\"name\":\"Alice\"}')")
|
|
75
|
+
result = db.query("SELECT JSON_EXTRACT(data, '$.name') FROM mydb.docs")
|
|
76
|
+
|
|
77
|
+
# Bulk CSV import/export with COPY INTO
|
|
78
|
+
db.execute("COPY INTO '/tmp/users.csv' FROM mydb.users") # Export
|
|
79
|
+
db.execute("COPY INTO mydb.users FROM '/tmp/users.csv'") # Import
|
|
52
80
|
```
|
|
53
81
|
|
|
54
82
|
### Embedded Mode (no server required)
|
|
Binary file
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: commitdb
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: Python driver for CommitDB SQL Server
|
|
5
5
|
Author: CommitDB Contributors
|
|
6
6
|
License: Apache-2.0
|
|
@@ -62,6 +62,9 @@ with CommitDB('localhost', 3306) as db:
|
|
|
62
62
|
# Insert data
|
|
63
63
|
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')")
|
|
64
64
|
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (2, 'Bob', 'bob@example.com')")
|
|
65
|
+
|
|
66
|
+
# Bulk insert (multiple rows in one statement)
|
|
67
|
+
db.execute("INSERT INTO mydb.users (id, name, email) VALUES (3, 'Charlie', 'c@example.com'), (4, 'Diana', 'd@example.com')")
|
|
65
68
|
|
|
66
69
|
# Query data - returns iterable of dictionaries
|
|
67
70
|
result = db.query('SELECT * FROM mydb.users')
|
|
@@ -70,7 +73,32 @@ with CommitDB('localhost', 3306) as db:
|
|
|
70
73
|
print(f" {row['id']}: {row['name']} ({row['email']})")
|
|
71
74
|
|
|
72
75
|
# Use convenience methods
|
|
73
|
-
db.insert('mydb', 'users', ['id', 'name', 'email'], [
|
|
76
|
+
db.insert('mydb', 'users', ['id', 'name', 'email'], [5, 'Eve', 'eve@example.com'])
|
|
77
|
+
|
|
78
|
+
# Use IN operator for multiple values
|
|
79
|
+
result = db.query("SELECT * FROM mydb.users WHERE id IN (1, 3)")
|
|
80
|
+
|
|
81
|
+
# Modify table schema
|
|
82
|
+
db.execute('ALTER TABLE mydb.users ADD COLUMN phone STRING')
|
|
83
|
+
db.execute('ALTER TABLE mydb.users RENAME COLUMN phone TO mobile')
|
|
84
|
+
db.execute('ALTER TABLE mydb.users DROP COLUMN mobile')
|
|
85
|
+
|
|
86
|
+
# Use string functions
|
|
87
|
+
result = db.query('SELECT UPPER(name) AS upper_name FROM mydb.users')
|
|
88
|
+
result = db.query("SELECT CONCAT(name, '@example.com') AS email FROM mydb.users")
|
|
89
|
+
|
|
90
|
+
# Use date functions
|
|
91
|
+
result = db.query('SELECT NOW() FROM mydb.users')
|
|
92
|
+
result = db.query("SELECT YEAR(created_at), MONTH(created_at) FROM mydb.events")
|
|
93
|
+
|
|
94
|
+
# Use JSON columns and functions
|
|
95
|
+
db.execute("CREATE TABLE mydb.docs (id INT PRIMARY KEY, data JSON)")
|
|
96
|
+
db.execute("INSERT INTO mydb.docs (id, data) VALUES (1, '{\"name\":\"Alice\"}')")
|
|
97
|
+
result = db.query("SELECT JSON_EXTRACT(data, '$.name') FROM mydb.docs")
|
|
98
|
+
|
|
99
|
+
# Bulk CSV import/export with COPY INTO
|
|
100
|
+
db.execute("COPY INTO '/tmp/users.csv' FROM mydb.users") # Export
|
|
101
|
+
db.execute("COPY INTO mydb.users FROM '/tmp/users.csv'") # Import
|
|
74
102
|
```
|
|
75
103
|
|
|
76
104
|
### Embedded Mode (no server required)
|
|
@@ -318,6 +318,149 @@ class TestCommitDBLocal:
|
|
|
318
318
|
with pytest.raises(CommitDBError):
|
|
319
319
|
db.query('SELECT * FROM nonexistent.table')
|
|
320
320
|
|
|
321
|
+
def test_in_operator(self, db):
|
|
322
|
+
"""Test IN operator for filtering."""
|
|
323
|
+
db.execute('CREATE DATABASE in_test')
|
|
324
|
+
db.execute('CREATE TABLE in_test.items (id INT PRIMARY KEY, status STRING, category STRING)')
|
|
325
|
+
|
|
326
|
+
# Insert test data
|
|
327
|
+
db.execute("INSERT INTO in_test.items (id, status, category) VALUES (1, 'active', 'A')")
|
|
328
|
+
db.execute("INSERT INTO in_test.items (id, status, category) VALUES (2, 'pending', 'B')")
|
|
329
|
+
db.execute("INSERT INTO in_test.items (id, status, category) VALUES (3, 'active', 'C')")
|
|
330
|
+
db.execute("INSERT INTO in_test.items (id, status, category) VALUES (4, 'archived', 'A')")
|
|
331
|
+
db.execute("INSERT INTO in_test.items (id, status, category) VALUES (5, 'pending', 'B')")
|
|
332
|
+
|
|
333
|
+
# Test IN with strings
|
|
334
|
+
result = db.query("SELECT * FROM in_test.items WHERE status IN ('active', 'pending')")
|
|
335
|
+
assert len(result) == 4
|
|
336
|
+
|
|
337
|
+
# Test IN with single value
|
|
338
|
+
result = db.query("SELECT * FROM in_test.items WHERE status IN ('archived')")
|
|
339
|
+
assert len(result) == 1
|
|
340
|
+
|
|
341
|
+
# Test IN with integers
|
|
342
|
+
result = db.query("SELECT * FROM in_test.items WHERE id IN (1, 3, 5)")
|
|
343
|
+
assert len(result) == 3
|
|
344
|
+
|
|
345
|
+
# Test NOT IN
|
|
346
|
+
result = db.query("SELECT * FROM in_test.items WHERE NOT status IN ('archived')")
|
|
347
|
+
assert len(result) == 4
|
|
348
|
+
|
|
349
|
+
def test_alter_table(self, db):
|
|
350
|
+
"""Test ALTER TABLE operations."""
|
|
351
|
+
db.execute('CREATE DATABASE alter_test')
|
|
352
|
+
db.execute('CREATE TABLE alter_test.users (id INT PRIMARY KEY, name STRING)')
|
|
353
|
+
|
|
354
|
+
# Test ADD COLUMN
|
|
355
|
+
result = db.execute('ALTER TABLE alter_test.users ADD COLUMN email STRING')
|
|
356
|
+
assert isinstance(result, CommitResult)
|
|
357
|
+
|
|
358
|
+
# Verify column was added
|
|
359
|
+
result = db.query('DESCRIBE alter_test.users')
|
|
360
|
+
assert len(result) == 3
|
|
361
|
+
|
|
362
|
+
# Test MODIFY COLUMN
|
|
363
|
+
result = db.execute('ALTER TABLE alter_test.users MODIFY COLUMN email TEXT')
|
|
364
|
+
assert isinstance(result, CommitResult)
|
|
365
|
+
|
|
366
|
+
# Test RENAME COLUMN
|
|
367
|
+
result = db.execute('ALTER TABLE alter_test.users RENAME COLUMN email TO contact')
|
|
368
|
+
assert isinstance(result, CommitResult)
|
|
369
|
+
|
|
370
|
+
# Verify rename
|
|
371
|
+
result = db.query('DESCRIBE alter_test.users')
|
|
372
|
+
column_names = [row['Column'] for row in result]
|
|
373
|
+
assert 'contact' in column_names
|
|
374
|
+
assert 'email' not in column_names
|
|
375
|
+
|
|
376
|
+
# Test DROP COLUMN
|
|
377
|
+
result = db.execute('ALTER TABLE alter_test.users DROP COLUMN contact')
|
|
378
|
+
assert isinstance(result, CommitResult)
|
|
379
|
+
|
|
380
|
+
# Verify column was dropped
|
|
381
|
+
result = db.query('DESCRIBE alter_test.users')
|
|
382
|
+
assert len(result) == 2
|
|
383
|
+
|
|
384
|
+
def test_string_functions(self, db):
|
|
385
|
+
"""Test string functions like UPPER, LOWER, CONCAT, etc."""
|
|
386
|
+
db.execute('CREATE DATABASE strfunc_test')
|
|
387
|
+
db.execute('CREATE TABLE strfunc_test.data (id INT PRIMARY KEY, name STRING)')
|
|
388
|
+
|
|
389
|
+
db.execute("INSERT INTO strfunc_test.data (id, name) VALUES (1, 'Alice')")
|
|
390
|
+
db.execute("INSERT INTO strfunc_test.data (id, name) VALUES (2, 'Bob')")
|
|
391
|
+
|
|
392
|
+
# Test UPPER
|
|
393
|
+
result = db.query('SELECT UPPER(name) FROM strfunc_test.data WHERE id = 1')
|
|
394
|
+
assert len(result) == 1
|
|
395
|
+
assert list(result[0].values())[0] == 'ALICE'
|
|
396
|
+
|
|
397
|
+
# Test LOWER
|
|
398
|
+
result = db.query('SELECT LOWER(name) FROM strfunc_test.data WHERE id = 1')
|
|
399
|
+
assert len(result) == 1
|
|
400
|
+
assert list(result[0].values())[0] == 'alice'
|
|
401
|
+
|
|
402
|
+
# Test LENGTH
|
|
403
|
+
result = db.query('SELECT LENGTH(name) FROM strfunc_test.data WHERE id = 2')
|
|
404
|
+
assert len(result) == 1
|
|
405
|
+
assert list(result[0].values())[0] == '3'
|
|
406
|
+
|
|
407
|
+
# Test CONCAT
|
|
408
|
+
result = db.query("SELECT CONCAT(name, '-test') FROM strfunc_test.data WHERE id = 1")
|
|
409
|
+
assert len(result) == 1
|
|
410
|
+
assert list(result[0].values())[0] == 'Alice-test'
|
|
411
|
+
|
|
412
|
+
def test_date_functions(self, db):
|
|
413
|
+
"""Test date functions like NOW, YEAR, MONTH, DAY, etc."""
|
|
414
|
+
db.execute('CREATE DATABASE datefunc_test')
|
|
415
|
+
db.execute('CREATE TABLE datefunc_test.events (id INT PRIMARY KEY, name STRING, created STRING)')
|
|
416
|
+
|
|
417
|
+
db.execute("INSERT INTO datefunc_test.events (id, name, created) VALUES (1, 'Event1', '2024-06-15 14:30:00')")
|
|
418
|
+
|
|
419
|
+
# Test NOW()
|
|
420
|
+
result = db.query('SELECT NOW() FROM datefunc_test.events WHERE id = 1')
|
|
421
|
+
assert len(result) == 1
|
|
422
|
+
assert len(list(result[0].values())[0]) > 0 # Non-empty
|
|
423
|
+
|
|
424
|
+
# Test YEAR
|
|
425
|
+
result = db.query('SELECT YEAR(created) FROM datefunc_test.events WHERE id = 1')
|
|
426
|
+
assert len(result) == 1
|
|
427
|
+
assert list(result[0].values())[0] == '2024'
|
|
428
|
+
|
|
429
|
+
# Test MONTH
|
|
430
|
+
result = db.query('SELECT MONTH(created) FROM datefunc_test.events WHERE id = 1')
|
|
431
|
+
assert len(result) == 1
|
|
432
|
+
assert list(result[0].values())[0] == '6'
|
|
433
|
+
|
|
434
|
+
# Test DAY
|
|
435
|
+
result = db.query('SELECT DAY(created) FROM datefunc_test.events WHERE id = 1')
|
|
436
|
+
assert len(result) == 1
|
|
437
|
+
assert list(result[0].values())[0] == '15'
|
|
438
|
+
|
|
439
|
+
# Test DATE
|
|
440
|
+
result = db.query('SELECT DATE(created) FROM datefunc_test.events WHERE id = 1')
|
|
441
|
+
assert len(result) == 1
|
|
442
|
+
assert list(result[0].values())[0] == '2024-06-15'
|
|
443
|
+
|
|
444
|
+
def test_date_columns(self, db):
|
|
445
|
+
"""Test DATE/TIMESTAMP column types and NOW() in INSERT."""
|
|
446
|
+
db.execute('CREATE DATABASE datecol_test')
|
|
447
|
+
db.execute('CREATE TABLE datecol_test.events (id INT PRIMARY KEY, name STRING, event_date DATE, created_at TIMESTAMP)')
|
|
448
|
+
|
|
449
|
+
# Test INSERT with NOW()
|
|
450
|
+
result = db.execute("INSERT INTO datecol_test.events (id, name, event_date, created_at) VALUES (1, 'Event1', '2024-06-15', NOW())")
|
|
451
|
+
assert isinstance(result, CommitResult)
|
|
452
|
+
|
|
453
|
+
# Verify the data was inserted
|
|
454
|
+
result = db.query('SELECT created_at FROM datecol_test.events WHERE id = 1')
|
|
455
|
+
assert len(result) == 1
|
|
456
|
+
assert len(list(result[0].values())[0]) > 0 # Non-empty timestamp
|
|
457
|
+
|
|
458
|
+
# Test NOW() for DATE column
|
|
459
|
+
db.execute("INSERT INTO datecol_test.events (id, name, event_date, created_at) VALUES (2, 'Event2', NOW(), '2024-12-25 08:00:00')")
|
|
460
|
+
result = db.query('SELECT event_date FROM datecol_test.events WHERE id = 2')
|
|
461
|
+
assert len(result) == 1
|
|
462
|
+
assert len(list(result[0].values())[0]) == 10 # Date format YYYY-MM-DD
|
|
463
|
+
|
|
321
464
|
def test_create_branch(self, db):
|
|
322
465
|
"""Test CREATE BRANCH SQL syntax."""
|
|
323
466
|
db.execute('CREATE DATABASE branch_test1')
|
|
@@ -355,6 +498,59 @@ class TestCommitDBLocal:
|
|
|
355
498
|
db.execute('CHECKOUT master')
|
|
356
499
|
result = db.query('SELECT * FROM branch_test2.data')
|
|
357
500
|
assert len(result) == 1
|
|
501
|
+
|
|
502
|
+
def test_bulk_insert(self, db):
|
|
503
|
+
"""Test bulk INSERT with multiple value rows."""
|
|
504
|
+
db.execute('CREATE DATABASE bulk_test')
|
|
505
|
+
db.execute('CREATE TABLE bulk_test.items (id INT PRIMARY KEY, name STRING, value INT)')
|
|
506
|
+
|
|
507
|
+
# Bulk insert multiple rows
|
|
508
|
+
result = db.execute("INSERT INTO bulk_test.items (id, name, value) VALUES (1, 'Item1', 100), (2, 'Item2', 200), (3, 'Item3', 300)")
|
|
509
|
+
assert result.records_written == 3
|
|
510
|
+
|
|
511
|
+
# Verify all rows were inserted
|
|
512
|
+
result = db.query('SELECT * FROM bulk_test.items ORDER BY id ASC')
|
|
513
|
+
assert len(result) == 3
|
|
514
|
+
assert result[0]['name'] == 'Item1'
|
|
515
|
+
assert result[1]['name'] == 'Item2'
|
|
516
|
+
assert result[2]['name'] == 'Item3'
|
|
517
|
+
|
|
518
|
+
def test_copy_into(self, db):
|
|
519
|
+
"""Test COPY INTO for bulk CSV import/export."""
|
|
520
|
+
import tempfile
|
|
521
|
+
import os
|
|
522
|
+
|
|
523
|
+
db.execute('CREATE DATABASE copy_test')
|
|
524
|
+
db.execute('CREATE TABLE copy_test.users (id INT PRIMARY KEY, name STRING, email STRING)')
|
|
525
|
+
|
|
526
|
+
# Insert data
|
|
527
|
+
db.execute("INSERT INTO copy_test.users (id, name, email) VALUES (1, 'Alice', 'alice@test.com')")
|
|
528
|
+
db.execute("INSERT INTO copy_test.users (id, name, email) VALUES (2, 'Bob', 'bob@test.com')")
|
|
529
|
+
|
|
530
|
+
# Export to CSV
|
|
531
|
+
with tempfile.NamedTemporaryFile(mode='w', suffix='.csv', delete=False) as f:
|
|
532
|
+
export_path = f.name
|
|
533
|
+
|
|
534
|
+
try:
|
|
535
|
+
result = db.execute(f"COPY INTO '{export_path}' FROM copy_test.users")
|
|
536
|
+
assert result.records_written == 2
|
|
537
|
+
|
|
538
|
+
# Verify file exists and has content
|
|
539
|
+
with open(export_path, 'r') as f:
|
|
540
|
+
content = f.read()
|
|
541
|
+
assert 'Alice' in content
|
|
542
|
+
assert 'id,name,email' in content
|
|
543
|
+
|
|
544
|
+
# Create new table and import
|
|
545
|
+
db.execute('CREATE TABLE copy_test.imported (id INT PRIMARY KEY, name STRING, email STRING)')
|
|
546
|
+
result = db.execute(f"COPY INTO copy_test.imported FROM '{export_path}'")
|
|
547
|
+
assert result.records_written == 2
|
|
548
|
+
|
|
549
|
+
# Verify imported data
|
|
550
|
+
result = db.query('SELECT * FROM copy_test.imported')
|
|
551
|
+
assert len(result) == 2
|
|
552
|
+
finally:
|
|
553
|
+
os.unlink(export_path)
|
|
358
554
|
|
|
359
555
|
def test_merge(self, db):
|
|
360
556
|
"""Test MERGE SQL syntax."""
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|