@@ -1596,18 +1596,8 @@ def test_create_table_w_schema_and_query(self):
1596
1596
{
1597
1597
"schema" : {
1598
1598
"fields" : [
1599
- {
1600
- "name" : "full_name" ,
1601
- "type" : "STRING" ,
1602
- "mode" : "REQUIRED" ,
1603
- "description" : None ,
1604
- },
1605
- {
1606
- "name" : "age" ,
1607
- "type" : "INTEGER" ,
1608
- "mode" : "REQUIRED" ,
1609
- "description" : None ,
1610
- },
1599
+ {"name" : "full_name" , "type" : "STRING" , "mode" : "REQUIRED" },
1600
+ {"name" : "age" , "type" : "INTEGER" , "mode" : "REQUIRED" },
1611
1601
]
1612
1602
},
1613
1603
"view" : {"query" : query },
@@ -1641,18 +1631,8 @@ def test_create_table_w_schema_and_query(self):
1641
1631
},
1642
1632
"schema" : {
1643
1633
"fields" : [
1644
- {
1645
- "name" : "full_name" ,
1646
- "type" : "STRING" ,
1647
- "mode" : "REQUIRED" ,
1648
- "description" : None ,
1649
- },
1650
- {
1651
- "name" : "age" ,
1652
- "type" : "INTEGER" ,
1653
- "mode" : "REQUIRED" ,
1654
- "description" : None ,
1655
- },
1634
+ {"name" : "full_name" , "type" : "STRING" , "mode" : "REQUIRED" },
1635
+ {"name" : "age" , "type" : "INTEGER" , "mode" : "REQUIRED" },
1656
1636
]
1657
1637
},
1658
1638
"view" : {"query" : query , "useLegacySql" : False },
@@ -2602,7 +2582,7 @@ def test_update_table(self):
2602
2582
"name" : "age" ,
2603
2583
"type" : "INTEGER" ,
2604
2584
"mode" : "REQUIRED" ,
2605
- "description" : None ,
2585
+ "description" : "New field description" ,
2606
2586
},
2607
2587
]
2608
2588
},
@@ -2613,8 +2593,10 @@ def test_update_table(self):
2613
2593
}
2614
2594
)
2615
2595
schema = [
2616
- SchemaField ("full_name" , "STRING" , mode = "REQUIRED" ),
2617
- SchemaField ("age" , "INTEGER" , mode = "REQUIRED" ),
2596
+ SchemaField ("full_name" , "STRING" , mode = "REQUIRED" , description = None ),
2597
+ SchemaField (
2598
+ "age" , "INTEGER" , mode = "REQUIRED" , description = "New field description"
2599
+ ),
2618
2600
]
2619
2601
creds = _make_credentials ()
2620
2602
client = self ._make_one (project = self .PROJECT , credentials = creds )
@@ -2647,7 +2629,7 @@ def test_update_table(self):
2647
2629
"name" : "age" ,
2648
2630
"type" : "INTEGER" ,
2649
2631
"mode" : "REQUIRED" ,
2650
- "description" : None ,
2632
+ "description" : "New field description" ,
2651
2633
},
2652
2634
]
2653
2635
},
@@ -2773,13 +2755,24 @@ def test_update_table_w_query(self):
2773
2755
"name" : "age" ,
2774
2756
"type" : "INTEGER" ,
2775
2757
"mode" : "REQUIRED" ,
2776
- "description" : None ,
2758
+ "description" : "this is a column" ,
2777
2759
},
2760
+ {"name" : "country" , "type" : "STRING" , "mode" : "NULLABLE" },
2778
2761
]
2779
2762
}
2780
2763
schema = [
2781
- SchemaField ("full_name" , "STRING" , mode = "REQUIRED" ),
2782
- SchemaField ("age" , "INTEGER" , mode = "REQUIRED" ),
2764
+ SchemaField (
2765
+ "full_name" ,
2766
+ "STRING" ,
2767
+ mode = "REQUIRED" ,
2768
+ # Explicitly unset the description.
2769
+ description = None ,
2770
+ ),
2771
+ SchemaField (
2772
+ "age" , "INTEGER" , mode = "REQUIRED" , description = "this is a column"
2773
+ ),
2774
+ # Omit the description to not make updates to it.
2775
+ SchemaField ("country" , "STRING" ),
2783
2776
]
2784
2777
resource = self ._make_table_resource ()
2785
2778
resource .update (
@@ -7658,18 +7651,47 @@ def test_load_table_from_file_w_invalid_job_config(self):
7658
7651
def test_load_table_from_dataframe (self ):
7659
7652
from google .cloud .bigquery .client import _DEFAULT_NUM_RETRIES
7660
7653
from google .cloud .bigquery import job
7661
- from google .cloud .bigquery .schema import SchemaField
7654
+ from google .cloud .bigquery .schema import PolicyTagList , SchemaField
7662
7655
7663
7656
client = self ._make_client ()
7664
- records = [{"id" : 1 , "age" : 100 }, {"id" : 2 , "age" : 60 }]
7665
- dataframe = pandas .DataFrame (records )
7657
+ records = [
7658
+ {"id" : 1 , "age" : 100 , "accounts" : [2 , 3 ]},
7659
+ {"id" : 2 , "age" : 60 , "accounts" : [5 ]},
7660
+ {"id" : 3 , "age" : 40 , "accounts" : []},
7661
+ ]
7662
+ # Mixup column order so that we can verify sent schema matches the
7663
+ # serialized order, not the table column order.
7664
+ column_order = ["age" , "accounts" , "id" ]
7665
+ dataframe = pandas .DataFrame (records , columns = column_order )
7666
+ table_fields = {
7667
+ "id" : SchemaField (
7668
+ "id" ,
7669
+ "INTEGER" ,
7670
+ mode = "REQUIRED" ,
7671
+ description = "integer column" ,
7672
+ policy_tags = PolicyTagList (names = ("foo" , "bar" )),
7673
+ ),
7674
+ "age" : SchemaField (
7675
+ "age" ,
7676
+ "INTEGER" ,
7677
+ mode = "NULLABLE" ,
7678
+ description = "age column" ,
7679
+ policy_tags = PolicyTagList (names = ("baz" ,)),
7680
+ ),
7681
+ "accounts" : SchemaField (
7682
+ "accounts" , "INTEGER" , mode = "REPEATED" , description = "array column" ,
7683
+ ),
7684
+ }
7685
+ get_table_schema = [
7686
+ table_fields ["id" ],
7687
+ table_fields ["age" ],
7688
+ table_fields ["accounts" ],
7689
+ ]
7666
7690
7667
7691
get_table_patch = mock .patch (
7668
7692
"google.cloud.bigquery.client.Client.get_table" ,
7669
7693
autospec = True ,
7670
- return_value = mock .Mock (
7671
- schema = [SchemaField ("id" , "INTEGER" ), SchemaField ("age" , "INTEGER" )]
7672
- ),
7694
+ return_value = mock .Mock (schema = get_table_schema ),
7673
7695
)
7674
7696
load_patch = mock .patch (
7675
7697
"google.cloud.bigquery.client.Client.load_table_from_file" , autospec = True
@@ -7695,8 +7717,21 @@ def test_load_table_from_dataframe(self):
7695
7717
sent_file = load_table_from_file .mock_calls [0 ][1 ][1 ]
7696
7718
assert sent_file .closed
7697
7719
7698
- sent_config = load_table_from_file .mock_calls [0 ][2 ]["job_config" ]
7699
- assert sent_config .source_format == job .SourceFormat .PARQUET
7720
+ sent_config = load_table_from_file .mock_calls [0 ][2 ]["job_config" ].to_api_repr ()[
7721
+ "load"
7722
+ ]
7723
+ assert sent_config ["sourceFormat" ] == job .SourceFormat .PARQUET
7724
+ for field_index , field in enumerate (sent_config ["schema" ]["fields" ]):
7725
+ assert field ["name" ] == column_order [field_index ]
7726
+ table_field = table_fields [field ["name" ]]
7727
+ assert field ["name" ] == table_field .name
7728
+ assert field ["type" ] == table_field .field_type
7729
+ assert field ["mode" ] == table_field .mode
7730
+ assert len (field .get ("fields" , [])) == len (table_field .fields )
7731
+ # Omit unnecessary fields when they come from getting the table
7732
+ # (not passed in via job_config)
7733
+ assert "description" not in field
7734
+ assert "policyTags" not in field
7700
7735
7701
7736
@unittest .skipIf (pandas is None , "Requires `pandas`" )
7702
7737
@unittest .skipIf (pyarrow is None , "Requires `pyarrow`" )
0 commit comments