|
58 | 58 | ) |
59 | 59 |
|
60 | 60 | if packaging.version.parse(sqlalchemy.__version__) >= packaging.version.parse("2.0"): |
| 61 | + import uuid |
61 | 62 | from sqlalchemy.sql import type_coerce |
62 | | - from sqlalchemy import create_engine |
| 63 | + from sqlalchemy import Uuid |
63 | 64 | from sqlalchemy.testing.suite import ( |
64 | 65 | TrueDivTest as _TrueDivTest, |
65 | 66 | IntegerTest as _IntegerTest, |
66 | 67 | NumericTest as _NumericTest, |
67 | 68 | DifficultParametersTest as _DifficultParametersTest, |
68 | 69 | FetchLimitOffsetTest as _FetchLimitOffsetTest, |
69 | | - PostCompileParamsTest as _PostCompileParamsTest, |
| 70 | + PostCompileParamsTest, |
| 71 | + UuidTest as _UuidTest, |
70 | 72 | ) |
71 | 73 |
|
72 | 74 | class TimestampMicrosecondsTest(_TimestampMicrosecondsTest): |
@@ -335,6 +337,111 @@ def test_limit_render_multiple_times(self, connection): |
335 | 337 | [(1,)], |
336 | 338 | ) |
337 | 339 |
|
| 340 | + class UuidTest(_UuidTest): |
| 341 | + @classmethod |
| 342 | + def define_tables(cls, metadata): |
| 343 | + Table( |
| 344 | + "uuid_table", |
| 345 | + metadata, |
| 346 | + Column("id", Integer, primary_key=True, test_needs_autoincrement=True), |
| 347 | + Column("uuid_data", String), # Use native UUID for primary data |
| 348 | + Column( |
| 349 | + "uuid_text_data", String, nullable=True |
| 350 | + ), # Optional text representation |
| 351 | + Column("uuid_data_nonnative", String), |
| 352 | + Column("uuid_text_data_nonnative", String), |
| 353 | + ) |
| 354 | + |
| 355 | + def test_uuid_round_trip(self, connection): |
| 356 | + data = str(uuid.uuid4()) |
| 357 | + uuid_table = self.tables.uuid_table |
| 358 | + |
| 359 | + connection.execute( |
| 360 | + uuid_table.insert(), |
| 361 | + {"id": 1, "uuid_data": data, "uuid_data_nonnative": data}, |
| 362 | + ) |
| 363 | + row = connection.execute( |
| 364 | + select(uuid_table.c.uuid_data, uuid_table.c.uuid_data_nonnative).where( |
| 365 | + uuid_table.c.uuid_data == data, |
| 366 | + uuid_table.c.uuid_data_nonnative == data, |
| 367 | + ) |
| 368 | + ).first() |
| 369 | + eq_(row, (data, data)) |
| 370 | + |
| 371 | + def test_uuid_text_round_trip(self, connection): |
| 372 | + data = str(uuid.uuid4()) |
| 373 | + uuid_table = self.tables.uuid_table |
| 374 | + |
| 375 | + connection.execute( |
| 376 | + uuid_table.insert(), |
| 377 | + { |
| 378 | + "id": 1, |
| 379 | + "uuid_text_data": data, |
| 380 | + "uuid_text_data_nonnative": data, |
| 381 | + }, |
| 382 | + ) |
| 383 | + row = connection.execute( |
| 384 | + select( |
| 385 | + uuid_table.c.uuid_text_data, |
| 386 | + uuid_table.c.uuid_text_data_nonnative, |
| 387 | + ).where( |
| 388 | + uuid_table.c.uuid_text_data == data, |
| 389 | + uuid_table.c.uuid_text_data_nonnative == data, |
| 390 | + ) |
| 391 | + ).first() |
| 392 | + eq_((row[0].lower(), row[1].lower()), (data, data)) |
| 393 | + |
| 394 | + def test_literal_uuid(self, literal_round_trip): |
| 395 | + data = str(uuid.uuid4()) |
| 396 | + literal_round_trip(String(), [data], [data]) |
| 397 | + |
| 398 | + def test_literal_text(self, literal_round_trip): |
| 399 | + data = str(uuid.uuid4()) |
| 400 | + literal_round_trip( |
| 401 | + String(), |
| 402 | + [data], |
| 403 | + [data], |
| 404 | + filter_=lambda x: x.lower(), |
| 405 | + ) |
| 406 | + |
| 407 | + def test_literal_nonnative_uuid(self, literal_round_trip): |
| 408 | + data = str(uuid.uuid4()) |
| 409 | + literal_round_trip(String(), [data], [data]) |
| 410 | + |
| 411 | + def test_literal_nonnative_text(self, literal_round_trip): |
| 412 | + data = str(uuid.uuid4()) |
| 413 | + literal_round_trip( |
| 414 | + String(), |
| 415 | + [data], |
| 416 | + [data], |
| 417 | + filter_=lambda x: x.lower(), |
| 418 | + ) |
| 419 | + |
| 420 | + @testing.requires.insert_returning |
| 421 | + def test_uuid_returning(self, connection): |
| 422 | + data = str(uuid.uuid4()) |
| 423 | + str_data = str(data) |
| 424 | + uuid_table = self.tables.uuid_table |
| 425 | + |
| 426 | + result = connection.execute( |
| 427 | + uuid_table.insert().returning( |
| 428 | + uuid_table.c.uuid_data, |
| 429 | + uuid_table.c.uuid_text_data, |
| 430 | + uuid_table.c.uuid_data_nonnative, |
| 431 | + uuid_table.c.uuid_text_data_nonnative, |
| 432 | + ), |
| 433 | + { |
| 434 | + "id": 1, |
| 435 | + "uuid_data": data, |
| 436 | + "uuid_text_data": str_data, |
| 437 | + "uuid_data_nonnative": data, |
| 438 | + "uuid_text_data_nonnative": str_data, |
| 439 | + }, |
| 440 | + ) |
| 441 | + row = result.first() |
| 442 | + |
| 443 | + eq_(row, (data, str_data, data, str_data)) |
| 444 | + |
338 | 445 | # from else statement .... |
339 | 446 | del DistinctOnTest # expects unquoted table names. |
340 | 447 | del HasIndexTest # BQ doesn't do the indexes that SQLA is loooking for. |
@@ -525,6 +632,13 @@ def insert_data(cls, connection): |
525 | 632 | ], |
526 | 633 | ) |
527 | 634 |
|
| 635 | + class InsertBehaviorTest(_InsertBehaviorTest): |
| 636 | + @pytest.mark.skip( |
| 637 | + "BQ has no autoinc and client-side defaults can't work for select." |
| 638 | + ) |
| 639 | + def test_insert_from_select_autoinc(cls): |
| 640 | + pass |
| 641 | + |
528 | 642 | class SimpleUpdateDeleteTest(_SimpleUpdateDeleteTest): |
529 | 643 | """The base tests fail if operations return rows for some reason.""" |
530 | 644 |
|
|
0 commit comments