Write rows to SQL Database from a function
Send write statements from a function to SQL Database through the Azion API, and check the result of every statement before you trust it.
You write rows to a database in SQL Database from a function through the Azion API, with a personal token that the function reads from an environment variable. To read rows inside a function, refer to Query a database from a function.
A function opens a database through a read replica, and that connection is read-only: a statement that writes fails with Error: SQLite failure: `attempt to write a readonly database` . The main instance takes every write, so the function sends its write statements to the query endpoint of the Azion API, which reaches it.
- The function reads the database identifier and the token from environment variables, and sends the statements to the query endpoint.
- A status outside 200 to 299 means the API rejected the whole request, and no statement ran.
- A
200carries one entry per statement. An entry witherroris a failed statement, even though the request succeeded. - When no entry carries
error, each statement ran, and itsresultsreport the rows it wrote.
Prerequisites
- SQL Database enabled on your account. The product is in Preview and is not enabled by default, so request access through Technical Support.
- A database, its identifier, and the table the function writes to. The identifier is the
idthe create response returns. To create them, refer to Create and manage databases and Create tables and query data. - A personal token for the function, separate from the one the Azion CLI uses. The account that owns it needs the Edit SQL Database permission. A token expires 1 day after it is created unless you choose a longer expiration, and every write fails once it expires, so set an expiration that covers the time the function runs.
- The Azion CLI installed and authorized, to store the environment variables.
- A function project to add the code to. To create and deploy one, refer to Deploy a function with Azion CLI.
The examples write to a table created with CREATE TABLE items (id INTEGER PRIMARY KEY AUTOINCREMENT, name TEXT NOT NULL);, and store the identifier and the token as SQL_DATABASE_ID and SQL_TOKEN. Replace them, <database-id>, and <personal-token> with your own values.
Store the database identifier and the token
The function reads both values at run time, so neither enters the code or its repository. The identifier is not confidential, and the token is: a secret variable is never printed back by the CLI. A key that contains token is sent as a secret by default.
To create the two variables with the Azion CLI:
Each command prints the UUID of the variable it created:
A change to a variable reaches a function only after the function is deployed again, so create both before you deploy the code in the next section. The account holds both variables, and the function reads each one with Azion.env.get(). For the limits on variables, refer to Environment variables.
Send the statements from the function
The query endpoint takes a statements array of SQL strings, runs them in order, and returns one entry per statement in data. A call carrying 100 statements succeeds, so a set of related writes travels in one call. The body carries SQL text and no parameters, so a text value goes inside the statement: quote it, double each single quote it holds, and validate it before it reaches a statement.
To write a row, add this code to the function’s entrypoint:
writeRows checks the result in two places, because a write fails in two places:
-
The request. A status outside 200 to 299 means the API rejected the whole call. When the statements cannot be executed at all, the API answers
422with code14005Execute SQL Exception. -
Each statement. A statement that fails does not fail the request. The call answers
200, and that statement’s entry carrieserrorin place ofresults:
A client that reads only the HTTP status reports that write as a success, and the row is never written. For every error code and error string, refer to Databases and queries.
Deploy the function, as Deploy a function with Azion CLI shows. A successful statement returns an entry whose results carries rows_written, the rows that statement wrote:
A POST to the function with a name adds one row to items, and the function answers 201 with rows_written set to 1. A failed write answers 500, and the function logs the status or the error string. To read that log line, refer to Query function console logs.
Confirm the rows were written
The function’s answer reports what the API returned. To read the rows back from the table, send a SELECT to the same query endpoint:
The API answers 200, and the entry’s results carries one array per row in rows, with the values in the order of columns:
The table holds the rows the function wrote. A function reading the same table through Database.open reads them from a read replica. For how the main instance and the replicas split the work, refer to How SQL Database works.