github.com/snowflakedb/gosnowflake@v1.9.0/cmd/filestransfer/filestransfer.go (about)

     1  // Example: Files transfer using PUT/GET commands
     2  //
     3  // This example shows how to transfer files to staging area, from which data can be loaded into snowflake
     4  // database tables. Apart from sending files to staging area using PUT command, files can also be downloaded
     5  // using GET command.
     6  package main
     7  
     8  import (
     9  	"bytes"
    10  	"compress/gzip"
    11  	"database/sql"
    12  	"flag"
    13  	"fmt"
    14  	"log"
    15  	"os"
    16  
    17  	sf "github.com/snowflakedb/gosnowflake"
    18  )
    19  
    20  const customFormatCsvDataToUpload = "NUM; TEXT\n1; foo\n2; bar\n3; baz"
    21  
    22  func createTmpFile(content string) string {
    23  	tempFile, err := os.CreateTemp("", "data_to_upload.csv")
    24  	if err != nil {
    25  		log.Fatalf("error during creating temp file; err: %v", err)
    26  	}
    27  	_, err = tempFile.Write([]byte(content))
    28  	if err != nil {
    29  		log.Fatalf("error during writing data to temp file; err: %v", err)
    30  	}
    31  	absolutePath := tempFile.Name()
    32  	fmt.Printf("Tmp file with data to upload created at %v with content %#v\n", absolutePath, customFormatCsvDataToUpload)
    33  	return absolutePath
    34  }
    35  
    36  func decompressAndRead(file *os.File) (string, error) {
    37  	gzipReader, err := gzip.NewReader(file)
    38  	defer gzipReader.Close()
    39  	if err != nil {
    40  		return "", err
    41  	}
    42  	var b bytes.Buffer
    43  	_, err = b.ReadFrom(gzipReader)
    44  	if err != nil {
    45  		return "", err
    46  	}
    47  	return b.String(), nil
    48  }
    49  
    50  func printRows(rows *sql.Rows) {
    51  	for i := 1; rows.Next(); i++ {
    52  		var col1 int
    53  		var col2 string
    54  		if err := rows.Scan(&col1, &col2); err != nil {
    55  			log.Fatalf("error while scaning rows; err: %v", err)
    56  		}
    57  		fmt.Printf("Row %v: %v, %v\n", i, col1, col2)
    58  	}
    59  }
    60  
    61  func main() {
    62  	if !flag.Parsed() {
    63  		flag.Parse()
    64  	}
    65  
    66  	cfg, err := sf.GetConfigFromEnv([]*sf.ConfigParam{
    67  		{Name: "Account", EnvName: "SNOWFLAKE_TEST_ACCOUNT", FailOnMissing: true},
    68  		{Name: "User", EnvName: "SNOWFLAKE_TEST_USER", FailOnMissing: true},
    69  		{Name: "Password", EnvName: "SNOWFLAKE_TEST_PASSWORD", FailOnMissing: true},
    70  		{Name: "Database", EnvName: "SNOWFLAKE_TEST_DATABASE", FailOnMissing: true},
    71  		{Name: "Schema", EnvName: "SNOWFLAKE_TEST_SCHEMA", FailOnMissing: true},
    72  		{Name: "Warehouse", EnvName: "SNOWFLAKE_TEST_WAREHOUSE", FailOnMissing: true},
    73  		{Name: "Host", EnvName: "SNOWFLAKE_TEST_HOST", FailOnMissing: false},
    74  		{Name: "Port", EnvName: "SNOWFLAKE_TEST_PORT", FailOnMissing: false},
    75  		{Name: "Protocol", EnvName: "SNOWFLAKE_TEST_PROTOCOL", FailOnMissing: false},
    76  	})
    77  	if err != nil {
    78  		log.Fatalf("failed to create Config, err: %v", err)
    79  	}
    80  	dsn, err := sf.DSN(cfg)
    81  	if err != nil {
    82  		log.Fatalf("failed to create DSN from Config: %v, err: %v", cfg, err)
    83  	}
    84  
    85  	db, err := sql.Open("snowflake", dsn)
    86  	defer db.Close()
    87  
    88  	//Creating table to which the data from CSV file will be copied
    89  	_, err = db.Exec("CREATE OR REPLACE TABLE GOSNOWFLAKE_FILES_TRANSFER_EXAMPLE(num integer, text varchar);")
    90  	if err != nil {
    91  		log.Fatalf("error while creating table; err: %v", err)
    92  	}
    93  	defer db.Exec("DROP TABLE IF EXISTS GOSNOWFLAKE_FILES_TRANSFER_EXAMPLE;")
    94  
    95  	//Uploading data_to_upload.csv to internal stage for table GOSNOWFLAKE_FILES_TRANSFER_EXAMPLE
    96  	tmpFilePath := createTmpFile(customFormatCsvDataToUpload)
    97  	defer os.Remove(tmpFilePath)
    98  	_, err = db.Exec(fmt.Sprintf("PUT file://%v @%%GOSNOWFLAKE_FILES_TRANSFER_EXAMPLE;", tmpFilePath))
    99  	if err != nil {
   100  		log.Fatalf("error while uploading file; err: %v", err)
   101  	}
   102  	fmt.Println("data_do_upload.csv successfully uploaded to internal stage.")
   103  
   104  	//Creating custom file format that describes our data
   105  	_, err = db.Exec("CREATE OR REPLACE TEMPORARY FILE FORMAT CUSTOM_CSV_FORMAT" +
   106  		" TYPE = CSV COMPRESSION = GZIP FIELD_DELIMITER = ';' FILE_EXTENSION = 'csv' SKIP_HEADER = 1;")
   107  	if err != nil {
   108  		log.Fatalf("error while creating file format; err: %v", err)
   109  	}
   110  	fmt.Println("Custom CSV format successfully created.")
   111  
   112  	//Loading data from files in stage area into table
   113  	_, err = db.Exec("COPY INTO GOSNOWFLAKE_FILES_TRANSFER_EXAMPLE FILE_FORMAT = CUSTOM_CSV_FORMAT;")
   114  	if err != nil {
   115  		log.Fatalf("error while copying data into table; err: %v", err)
   116  	}
   117  	fmt.Println("Data successfully loaded into table. Querying...")
   118  
   119  	//Querying loaded data from table
   120  	rows, err := db.Query("SELECT * FROM GOSNOWFLAKE_FILES_TRANSFER_EXAMPLE;")
   121  	if err != nil {
   122  		log.Fatalf("error while querying data from table; err: %v", err)
   123  	}
   124  	defer rows.Close()
   125  	printRows(rows)
   126  
   127  	//Downloading file from stage area to system's TMP directory
   128  	tmpDir := os.TempDir()
   129  	_, err = db.Exec(fmt.Sprintf("GET @%%GOSNOWFLAKE_FILES_TRANSFER_EXAMPLE/data_to_upload.csv file://%v/;", tmpDir))
   130  	if err != nil {
   131  		log.Fatalf("error while downloading data from internal stage area; err: %v", err)
   132  	}
   133  	fmt.Printf("File successfully downloaded from internal stage area to %v\n", tmpDir)
   134  
   135  	//Reading from downloaded file
   136  	file, err := os.Open(fmt.Sprintf("%v/data_to_upload.csv.gz", tmpDir))
   137  	if err != nil {
   138  		log.Fatalf("error while opening downloaded file; err: %v", err)
   139  	}
   140  	content, err := decompressAndRead(file)
   141  	if err != nil {
   142  		log.Fatalf("error while reading file; err: %v", err)
   143  	}
   144  	fmt.Printf("Downloaded file content: %#v\n", content)
   145  }