For this tutorial you need to download the sample data files provided by Snowflake.
To download and unzip the sample data files:
Right-click the name of the
archive file, data-load-internal.zip
and save the link/file to your local file system.
Unzip the sample files. The tutorial assumes you unpacked files in
to the following directories:
Linux/macOS: /tmp/load
Windows: C:\temp\load
These data files include sample contact data in the following formats:
CSV files that contain a header row and five records. The field
delimiter is the pipe (|) character.
The following example shows a header row and one record:
Start an interactive Snowflake CLI session and run every SQL statement in this tutorial at that prompt. Keep the session open until you finish the tutorial, including the clean-up commands. The temporary tables in this tutorial last only for this session, and the USE statements apply only here.
snow sql
End each SQL statement with a semicolon (;). To leave the session after the tutorial, enter exit.
File uploads later in this tutorial use snow stage copy in a second terminal. Leave this snow sql session running while you upload. The named stages are stored in mydatabase, so the upload command can write to them. When the upload finishes, return to this same session for the next SQL statement.
In the snow sql session, execute the following statements to create a database, two tables
(for csv and json data), and a virtual warehouse needed for this tutorial.
After you complete the tutorial, you can drop these objects.
-- Create a database. A database automatically includes a schema named 'public'.CREATE OR REPLACEDATABASE mydatabase;-- Create a warehouseCREATE OR REPLACEWAREHOUSE mywarehouse WITHWAREHOUSE_SIZE='X-SMALL'AUTO_SUSPEND=120AUTO_RESUME=TRUEINITIALLY_SUSPENDED=TRUE;-- Set the database, schema, and warehouse for the rest of this session.USEDATABASE mydatabase;USESCHEMApublic;USEWAREHOUSE mywarehouse;/* Create target tables for CSV and JSON data. The tables are temporary, meaning they persist only for the duration of the user session and are not visible to other users. */CREATE OR REPLACETEMPORARYTABLE mycsvtable (
id INTEGER,last_nameSTRING,first_nameSTRING,
company STRING,emailSTRING,
workphone STRING,
cellphone STRING,
streetaddress STRING,
city STRING,
postalcode STRING);CREATE OR REPLACETEMPORARYTABLE myjsontable (
json_data VARIANT);
The CREATE WAREHOUSE statement sets up the warehouse to be suspended initially.
The statement also sets AUTO_RESUME = true, which starts the warehouse automatically
when you execute SQL statements that require compute resources.
The USE statements set the database, schema, and warehouse for the rest of this session.
Later SQL in this tutorial uses unqualified object names, so run those statements here.
When you load data from a file into a table, you must describe the format of the file
and specify how the data in the file should be interpreted and processed. For example,
if you are loading pipe-delimited data from a CSV file, you must specify that the file
uses the CSV format with pipe symbols as delimiters.
When you execute the COPY INTO <table> command, you specify this format information. You can
either specify this information as options in the command (e.g.
TYPE = CSV, FIELD_DELIMITER = '|', etc.) or you can specify a
file format object that contains this format information. You can create a named file
format object using the CREATE FILE FORMAT command.
In this step, you create file format objects describing the data format of the sample CSV and
JSON data provided for this tutorial.
Execute the CREATE FILE FORMAT command
to create the mycsvformat file format.
CREATE OR REPLACEFILEFORMAT mycsvformat
TYPE='CSV'FIELD_DELIMITER='|'SKIP_HEADER=1;
Where:
TYPE = 'CSV' indicates the source file format type. CSV is the default file format type.
FIELD_DELIMITER = '|' indicates the ‘|’ character is a field separator. The default value is ‘,’.
SKIP_HEADER = 1 indicates the source file includes one header line. The COPY command skips these header lines when loading data. The default value is 0.
A stage specifies where data files are stored (i.e. “staged”) so that the data
in the files can be loaded into a table.
A named internal stage
is a cloud storage location managed by Snowflake.
Creating a named stage is useful if you want multiple users or processes
to upload files. If you plan to stage data files to load only
by you, or to load only into a single table, then you may prefer
to use your user stage or the table stage. For information, see
Bulk loading from a local file system.
In this step, you create named stages for the different types of sample data files.
Execute CREATE STAGE to create the my_csv_stage stage:
CREATE OR REPLACESTAGE my_csv_stage
FILE_FORMAT= mycsvformat;
Note that if you specify the FILE_FORMAT option when creating
the stage, it is not necessary to specify the same FILE_FORMAT
option in the COPY command used to load data from the stage.
Upload the sample data files from your local file system to the stages you created
earlier in this tutorial. In a second terminal, run
snow stage copy.
Leave the snow sql session open.
snow stage copy gzips files only when you pass --auto-compress. The COPY INTO steps
later in this tutorial load the .gz file names that gzip produces, so include that option.
Quote the local path so the shell passes the * glob to the command.
"/tmp/load/contacts*.csv" (or the Windows path) specifies the full directory path and names of the files on your local machine. Quote the path because it contains a wildcard.
@mydatabase.public.my_csv_stage is the fully qualified stage. The upload runs outside the snow sql session, so the stage name includes the database and schema.
--auto-compress gzips each file during the upload. The command leaves files uncompressed unless you set this option.
The command reports the staged files. With --auto-compress, the target names end in .gz, as in this result:
The FROM clause specifies the location of the staged data
file (stage name followed by the file name).
The ON_ERROR clause specifies what to do when the COPY command
encounters errors in the files. By default, the command stops
loading data when the first error is encountered; however, we’ve instructed it to skip any file containing an error and move on to loading the next file. Note that this is just for illustration purposes; none of the files in this tutorial contain errors.
The COPY command returns a result showing the name of the file copied and related information:
Load the rest of the staged files in the mycsvtable table.
The following example uses pattern matching to load data from all files
that match the regular expression .*contacts[1-5].csv.gz into the mycsvtable table.
In the CSV load, the COPY INTO command skipped one file when
it encountered the first error. You need to find all the errors and fix them.
In this step, you use the VALIDATE function
to validate the previous execution of the COPY INTO command and returns all errors.
Validate the sample data files and retrieve any errors¶
You need the query ID of the COPY INTO command that skipped contacts3.csv.gz.
Use the query ID you copied with LAST_QUERY_ID() after that statement.
Stay in the same snow sql session, then call the VALIDATE function with that query ID.
If you still need the query ID, list COPY queries from this session at the snow sql prompt. ! commands do not end with a semicolon. Copy the query ID for the earlier COPY INTO mycsvtable that reported a load error for contacts3.csv.gz. Skip the later COPY INTO that loaded contacts.json.gz.
!queries amount=5 type=COPY session
Validate the COPY INTO command execution, represented by the query ID,
and save errors to a new table named save_copy_errors.
In the same snow sql session, run the following command. Replace query_id with the query ID you copied.
CREATE OR REPLACETABLE save_copy_errors ASSELECT*FROMTABLE(VALIDATE(mycsvtable,JOB_ID=>'<query_id>'));
Query the save_copy_errors table.
SELECT*FROMSAVE_COPY_ERRORS;
The query returns the following results:
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------+------+-----------+-------------+----------+--------+-----------+-------------------------------+------------+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+
| ERROR | FILE | LINE | CHARACTER | BYTE_OFFSET | CATEGORY | CODE | SQL_STATE | COLUMN_NAME | ROW_NUMBER | ROW_START_LINE | REJECTED_RECORD |
|----------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------+------+-----------+-------------+----------+--------+-----------+-------------------------------+------------+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------|
| Number of columns in file (11) does not match that of the corresponding table (10), use file format option error_on_column_count_mismatch=false to ignore this error | mycsvtable/contacts3.csv.gz | 3 | 1 | 234 | parsing | 100080 | 22000 | "MYCSVTABLE"[11] | 1 | 2 | 11%Ishmael%Burnett|Dolor Elit Pellentesque Ltd|vitae.erat@necmollisvitae.ca%1-872%600-7301%1-513-592-6779%P.O. Box 975, 553 Odio, Road%Hulste%63345 |
| Field delimiter '|' found while expecting record delimiter '\n' | mycsvtable/contacts3.csv.gz | 5 | 125 | 625 | parsing | 100016 | 22000 | "MYCSVTABLE"["POSTALCODE":10] | 4 | 5 | 14|Sophia%Christian%Turpis Ltd|lectus.pede@non.ca|1-962-503-3253%1-157-%850-3602|P.O. Box 824, 7971 Sagittis Rd.|Chattanooga|56188 |
+----------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------------------------+------+-----------+-------------+----------+--------+-----------+-------------------------------+------------+----------------+-----------------------------------------------------------------------------------------------------------------------------------------------------+
The result shows two data errors in mycsvtable/contacts3.csv.gz:
Number of columns in file (11) does not match that of the corresponding table (10)
In Row 1, a hyphen was mistakenly replaced with the pipe (|) character, the data file delimiter, effectively creating an additional column in the record.
Field delimiter '|' found while expecting record delimiter 'n'
In Row 5, an additional pipe (|) character was introduced after a hyphen, breaking the record.
Fix the errors in the records manually in the contacts3.csv file in your local environment.
Upload the modified data file with snow stage copy in the second terminal. --overwrite replaces the existing staged file. Leave the snow sql session open, then return to it for the next COPY INTO statement.
After you verify that you successfully copied data from your stage into the tables,
you can remove data files from the internal stage using the REMOVE
command to save on data storage.