Modify Rows in a Table
Writing data is every bit as important to applications as reading.
This activity will delve deeper into how to insert, update, and delete data from the table we created in previous lessons. If you don't have a SXTTemp.Test_<your UserID>
table, go back and complete the "Create Your Own Table" activity first. We'll use the ADMIN_BISCUIT
we generated in that activity.
Space and Time is a data warehouse, meaning its as large-scale database that operates on SQL. This means it accepts DML - data manipulation language - the same as any other database. SXT Labs has taken special efforts to align Space and Time Database SQL syntax to PostgreSQL, an open source database popular with development teams. This should make SXT feel very familiar, for those used to PostgreSQL.
Let's Get Started!
To be able to validate your script, we'd ask that you generate a new file called Modify_Rows_In_Table.sh that you can commit to your branch of the SXT-Community/SXTAccreditation repo at the end of the activity.
Primary Key
Every table in Space and Time has a Primary Key(PK), which is one or more columns that can be used to uniquely identify the row. This columns cannot be null, and the combination of the columns must be unique.
For example, the table you've built has a single column PK defined on line 11: primary key(MyID)
CREATE TABLE SXTTemp.Test_<your UserID>
( MyID INTEGER
, MyBigint BIGINT
, MyText VARCHAR
, MyDate DATE
, MyBoolean BOOLEAN
, MyDecimal DECIMAL(18,2)
, MyFloat FLOAT
, MyJson JSONB
, MyTimestamp TIMESTAMP
, primary key(MyID)
)
with "public_key=$RESOURCE_PUBLIC_KEY,access_type=permissioned"
This means that the column MyID
must be unique, and cannot be null. It's important to understand this when modifying data, as doing inserts or updates that introduce duplication in PKs will always error.
Inserting Rows
The Basics:
INSERT statements are the primary way users of Space and Time insert custom data into the network. Broadly speaking, INSERT
statements have three parts:
INSERT INTO
and Table Name- Defining the column order
- Supplying the data
The order of columns and values must be the same between part 2 and 3. Unlike other data structures like JSON, SQL Inserts rely on positional coordination between the column names, and the data values being supplied.
For example - let's insert these 5 rows into our table above, using the SXTCLI so we can leave the heredoc structure, for readability:
INSERT_SQL=$(cat << EOM
INSERT INTO SXTTemp.Test_<your UserID>
(MyID, MyBigint, MyText, MyDate, MyBoolean, MyDecimal, MyFloat, MyJson, MyTimestamp)
VALUES
( 1, 1e12, 'Foo', '2024-10-31', true, 1.1, 1.11111 * 1e-9, '{"a":1, "b":2}', '2024-10-31 00:00:00' )
, ( 2, 2e12, 'Foo', '2024-10-31', true, 2.2, 1.22222 * 1e-9, '{"a":1, "b":2}', '2024-10-31 06:59:59' )
, ( 3, 3e12, 'Foo', '2024-10-31', true, 3.3, 1.33333 * 1e-9, '{"a":1, "b":2}', '2024-10-31 12:59:59' )
, ( 4, 4e12, 'Foo', '2024-10-31', true, 4.4, 1.44444 * 1e-9, '{"a":1, "b":2}', '2024-10-31 18:59:59' )
, ( 5, 5e12, 'Foo', '2024-10-31', true, 5.5, 1.55555 * 1e-9, '{"a":1, "b":2}', '2024-10-31 23:59:59' )
EOM
)
The first line of the SQL (line 3 of the script) specifies the SCHEMA and TABLENAME. The line below that lists all the columns for which data can be expected, and in what order. The keyword VALUES
indicates the beginning of data records, from one to several thousand.
Run the above example, using the SXTCLI. If you forgotten the `$ADMIN_BISCUIT, go back to the "Create Your Own Table" activity:
sxtcli sql \
--url=$API_URL \
--accessToken=$ACCESS_TOKEN \
--sqlText=$INSERT_SQL \
--biscuits=$ADMIN_BISCUIT
This will return the number of rows inserted:
[ {
"UPDATED" : 5
} ]
Optional Column List
Specifying the column list is optional if you are supplying data for every column. This means the INSERT statement above could also be structured as:
INSERT_SQL=$(cat << EOM
INSERT INTO SXTTemp.Test_<your UserID>
VALUES
( 6, 6e12, 'Foo', '2024-10-31', true, 6.6, 1.66666 * 1e-9, '{"a":1, "b":2}', '2024-10-31 23:59:59' )
, ( 7, 7e12, 'Foo', '2024-10-31', true, 7.7, 1.77777 * 1e-9, '{"a":1, "b":2}', '2024-10-31 23:59:59' )
, ( 8, 8e12, 'Foo', '2024-10-31', true, 8.8, 1.88888 * 1e-9, '{"a":1, "b":2}', '2024-10-31 23:59:59' )
EOM
)
sxtcli sql \
--url=$API_URL \
--accessToken=$ACCESS_TOKEN \
--sqlText=$INSERT_SQL \
--biscuits=$ADMIN_BISCUIT
[ {
"UPDATED" : 3
} ]
Partial Column List
You can also omit certain columns, if you don't have data to supply. All columns are optional except for the PK, or any columns defined as NOT NULL.
For example, we could supply only MyID (PK) and MyBoolean, however we are then required to specify the column list, and match the column order with the data provided:
INSERT_SQL=$(cat << EOM
INSERT INTO SXTTemp.Test_<your UserID>
(MyID, MyBoolean)
VALUES
( 9, true)
, ( 10, true)
EOM
)
sxtcli sql \
--url=$API_URL \
--accessToken=$ACCESS_TOKEN \
--sqlText=$INSERT_SQL \
--biscuits=$ADMIN_BISCUIT
[ {
"UPDATED" : 2
} ]
Remember, your PK can be multiple columns, but the combination of values must be unique. If you try to run the insert immediately above a second time, you'll get an error now instead:
sql failed
[500] Internal Server Error
Details: [73a40e47-a31a-421c-a847-5eda22029842] ERROR: duplicate key value violates unique constraint "test_<your UserID>_pkey"
Detail: Key (myid)=(9) already exists.
This is because you've already inserted the keys 9 and 10, and the table cannot have duplicate PK values. Likewise, trying to insert a NULL value (or omitting the PK from the insert) will result in a null value
error.
Updating Rows
Updating rows changes data that's already been inserted, and similarly have three major parts:
UPDATE
and Table NameSET
followed by a comma-delimited list of name-value pairsWHERE
statement, limiting which rows will be affected
As an example - let's change MyBoolean to False, and MyText to 'Bar' if MyID is an odd number:
UPDATE_SQL=$(cat << EOM
UPDATE SXTTemp.Test_<your UserID>
SET
MyBoolean = false
, MyText = 'Bar'
WHERE MyID in(1,3,5,7,9)
EOM
)
sxtcli sql \
--url=$API_URL \
--accessToken=$ACCESS_TOKEN \
--sqlText=$UPDATE_SQL \
--biscuits=$ADMIN_BISCUIT
As expected, this updates 5 rows. Note that in Space and Time Database, you can UPDATE the PK if you wish, so long as it doesn't cause a duplicate key violation.
Deleting Rows
Finally, you are allowed to delete rows, removing them from the database entirely.
Take Care! Once deleted, database records are simply gone - there is no "trash" for easy recovery!
Fortunately, DELETE statements are nearly identical to SELECT statements, minus the initial column selection list. Thus, it's a best practice to start writing DELETEs as a SELECT, so you can check the rows that will be deleted, before executing the DELETE statement.
DELETE_SQL=$(cat << EOM
SELECT * FROM SXTTemp.Test_<your UserID>
WHERE MyID between 1 and 5
EOM
)
sxtcli sql \
--url=$API_URL \
--accessToken=$ACCESS_TOKEN \
--sqlText=$DELETE_SQL \
--biscuits=$ADMIN_BISCUIT
If the above SELECT returns the rows you expect to be deleted, swap out SELECT *
for DELETE
and run again:
DELETE_SQL=$(cat << EOM
DELETE FROM SXTTemp.Test_<your UserID>
WHERE MyID between 1 and 5
EOM
)
sxtcli sql \
--url=$API_URL \
--accessToken=$ACCESS_TOKEN \
--sqlText=$DELETE_SQL \
--biscuits=$ADMIN_BISCUIT
Get Credit:
You'll get credit for this activity if you:
- Insert 10 rows into your table:
SXTTemp.Test_<your UserID>
- Update your table:
SXTTemp.Test_<your UserID>
so thatMyBoolean
is false whereMyID
is odd - Delete rows where MyID is 1 thru 5 in your table:
SXTTemp.Test_<your UserID>
- Commit your work file to the SXT-Community/SXTAccreditation repo
How should I commit my branch changes?
When you're complete with the activity, simply commit your changes to your branch of work, then push to the SXT-Community/SXTAccreditation repo. Many IDEs have automated processes to manage this for you, but to do this manually by opening a temrinal / WSL window, and typing:
If you get an error on line 5 saying, The current branch stephens_work has no upstream branch
, this is because Github doesn't know about your branch yet. Simply run the command the git tool recommends - it will look something like:
git push --set-upstream origin <your_branch>
When you're done for the day, head over to SXT-Community/SXTAccreditation/Pulls page on Github, and (if you're logged in) you'll see a message like:
Click on the button above to create a Pull Request, give us some feedback in the description, and click "Create Pull Request". Done!
Updated 24 days ago