23
23
import argparse
24
24
25
25
from google .cloud import spanner
26
+ from google .cloud .spanner_v1 import param_types
26
27
27
28
28
29
# [START spanner_create_database]
@@ -514,8 +515,7 @@ def insert_data_with_timestamp(instance_id, database_id):
514
515
515
516
# [START spanner_add_timestamp_column]
516
517
def add_timestamp_column (instance_id , database_id ):
517
- """
518
- Adds a new TIMESTAMP column to the Albums table in the example database.
518
+ """ Adds a new TIMESTAMP column to the Albums table in the example database.
519
519
"""
520
520
spanner_client = spanner .Client ()
521
521
instance = spanner_client .instance (instance_id )
@@ -598,6 +598,156 @@ def query_data_with_timestamp(instance_id, database_id):
598
598
# [END spanner_query_data_with_timestamp_column]
599
599
600
600
601
+ # [START spanner_write_data_for_struct_queries]
602
+ def write_struct_data (instance_id , database_id ):
603
+ """Inserts sample data that can be used to test STRUCT parameters
604
+ in queries.
605
+ """
606
+ spanner_client = spanner .Client ()
607
+ instance = spanner_client .instance (instance_id )
608
+ database = instance .database (database_id )
609
+
610
+ with database .batch () as batch :
611
+ batch .insert (
612
+ table = 'Singers' ,
613
+ columns = ('SingerId' , 'FirstName' , 'LastName' ,),
614
+ values = [
615
+ (6 , u'Elena' , u'Campbell' ),
616
+ (7 , u'Gabriel' , u'Wright' ),
617
+ (8 , u'Benjamin' , u'Martinez' ),
618
+ (9 , u'Hannah' , u'Harris' )])
619
+
620
+ print ('Inserted sample data for STRUCT queries' )
621
+ # [END spanner_write_data_for_struct_queries]
622
+
623
+
624
+ def query_with_struct (instance_id , database_id ):
625
+ """Query a table using STRUCT parameters. """
626
+ # [START spanner_create_struct_with_data]
627
+ record_type = param_types .Struct ([
628
+ param_types .StructField ('FirstName' , param_types .STRING ),
629
+ param_types .StructField ('LastName' , param_types .STRING )
630
+ ])
631
+ record_value = ('Elena' , 'Campbell' )
632
+ # [END spanner_create_struct_with_data]
633
+
634
+ # [START spanner_query_data_with_struct]
635
+ spanner_client = spanner .Client ()
636
+ instance = spanner_client .instance (instance_id )
637
+
638
+ database = instance .database (database_id )
639
+
640
+ with database .snapshot () as snapshot :
641
+ results = snapshot .execute_sql (
642
+ "SELECT SingerId FROM Singers WHERE "
643
+ "(FirstName, LastName) = @name" ,
644
+ params = {'name' : record_value },
645
+ param_types = {'name' : record_type })
646
+
647
+ for row in results :
648
+ print (u'SingerId: {}' .format (* row ))
649
+ # [END spanner_query_data_with_struct]
650
+
651
+
652
+ def query_with_array_of_struct (instance_id , database_id ):
653
+ """Query a table using an array of STRUCT parameters. """
654
+ # [START spanner_create_user_defined_struct]
655
+ name_type = param_types .Struct ([
656
+ param_types .StructField ('FirstName' , param_types .STRING ),
657
+ param_types .StructField ('LastName' , param_types .STRING )])
658
+ # [END spanner_create_user_defined_struct]
659
+
660
+ # [START spanner_create_array_of_struct_with_data]
661
+ band_members = [("Elena" , "Campbell" ),
662
+ ("Gabriel" , "Wright" ),
663
+ ("Benjamin" , "Martinez" )]
664
+ # [END spanner_create_array_of_struct_with_data]
665
+
666
+ # [START spanner_query_data_with_array_of_struct]
667
+ spanner_client = spanner .Client ()
668
+ instance = spanner_client .instance (instance_id )
669
+ database = instance .database (database_id )
670
+
671
+ with database .snapshot () as snapshot :
672
+ results = snapshot .execute_sql (
673
+ "SELECT SingerId FROM Singers WHERE "
674
+ "STRUCT<FirstName STRING, LastName STRING>"
675
+ "(FirstName, LastName) IN UNNEST(@names)" ,
676
+ params = {'names' : band_members },
677
+ param_types = {'names' : param_types .Array (name_type )})
678
+
679
+ for row in results :
680
+ print (u'SingerId: {}' .format (* row ))
681
+ # [END spanner_query_data_with_array_of_struct]
682
+
683
+
684
+ # [START spanner_field_access_on_struct_parameters]
685
+ def query_struct_field (instance_id , database_id ):
686
+ """Query a table using field access on a STRUCT parameter. """
687
+ spanner_client = spanner .Client ()
688
+ instance = spanner_client .instance (instance_id )
689
+ database = instance .database (database_id )
690
+
691
+ name_type = param_types .Struct ([
692
+ param_types .StructField ('FirstName' , param_types .STRING ),
693
+ param_types .StructField ('LastName' , param_types .STRING )
694
+ ])
695
+
696
+ with database .snapshot () as snapshot :
697
+ results = snapshot .execute_sql (
698
+ "SELECT SingerId FROM Singers "
699
+ "WHERE FirstName = @name.FirstName" ,
700
+ params = {'name' : ("Elena" , "Campbell" )},
701
+ param_types = {'name' : name_type })
702
+
703
+ for row in results :
704
+ print (u'SingerId: {}' .format (* row ))
705
+ # [START spanner_field_access_on_struct_parameters]
706
+
707
+
708
+ # [START spanner_field_access_on_nested_struct_parameters]
709
+ def query_nested_struct_field (instance_id , database_id ):
710
+ """Query a table using nested field access on a STRUCT parameter. """
711
+ spanner_client = spanner .Client ()
712
+ instance = spanner_client .instance (instance_id )
713
+ database = instance .database (database_id )
714
+
715
+ song_info_type = param_types .Struct ([
716
+ param_types .StructField ('SongName' , param_types .STRING ),
717
+ param_types .StructField (
718
+ 'ArtistNames' , param_types .Array (
719
+ param_types .Struct ([
720
+ param_types .StructField (
721
+ 'FirstName' , param_types .STRING ),
722
+ param_types .StructField (
723
+ 'LastName' , param_types .STRING )
724
+ ])
725
+ )
726
+ )
727
+ ])
728
+
729
+ song_info = ('Imagination' , [('Elena' , 'Campbell' ), ('Hannah' , 'Harris' )])
730
+
731
+ with database .snapshot () as snapshot :
732
+ results = snapshot .execute_sql (
733
+ "SELECT SingerId, @song_info.SongName "
734
+ "FROM Singers WHERE "
735
+ "STRUCT<FirstName STRING, LastName STRING>"
736
+ "(FirstName, LastName) "
737
+ "IN UNNEST(@song_info.ArtistNames)" ,
738
+ params = {
739
+ 'song_info' : song_info
740
+ },
741
+ param_types = {
742
+ 'song_info' : song_info_type
743
+ }
744
+ )
745
+
746
+ for row in results :
747
+ print (u'SingerId: {} SongName: {}' .format (* row ))
748
+ # [END spanner_field_access_on_nested_struct_parameters]
749
+
750
+
601
751
if __name__ == '__main__' : # noqa: C901
602
752
parser = argparse .ArgumentParser (
603
753
description = __doc__ ,
@@ -644,6 +794,14 @@ def query_data_with_timestamp(instance_id, database_id):
644
794
'update_data_with_timestamp' , help = update_data_with_timestamp .__doc__ )
645
795
subparsers .add_parser (
646
796
'query_data_with_timestamp' , help = query_data_with_timestamp .__doc__ )
797
+ subparsers .add_parser ('write_struct_data' , help = write_struct_data .__doc__ )
798
+ subparsers .add_parser ('query_with_struct' , help = query_with_struct .__doc__ )
799
+ subparsers .add_parser (
800
+ 'query_with_array_of_struct' , help = query_with_array_of_struct .__doc__ )
801
+ subparsers .add_parser (
802
+ 'query_struct_field' , help = query_struct_field .__doc__ )
803
+ subparsers .add_parser (
804
+ 'query_nested_struct_field' , help = query_nested_struct_field .__doc__ )
647
805
648
806
args = parser .parse_args ()
649
807
@@ -689,3 +847,13 @@ def query_data_with_timestamp(instance_id, database_id):
689
847
update_data_with_timestamp (args .instance_id , args .database_id )
690
848
elif args .command == 'query_data_with_timestamp' :
691
849
query_data_with_timestamp (args .instance_id , args .database_id )
850
+ elif args .command == 'write_struct_data' :
851
+ write_struct_data (args .instance_id , args .database_id )
852
+ elif args .command == 'query_with_struct' :
853
+ query_with_struct (args .instance_id , args .database_id )
854
+ elif args .command == 'query_with_array_of_struct' :
855
+ query_with_array_of_struct (args .instance_id , args .database_id )
856
+ elif args .command == 'query_struct_field' :
857
+ query_struct_field (args .instance_id , args .database_id )
858
+ elif args .command == 'query_nested_struct_field' :
859
+ query_nested_struct_field (args .instance_id , args .database_id )
0 commit comments