Skip to content

Commit 863b688

Browse files
Merge branch 'main' into triggerbindings
2 parents e8d9506 + c722f42 commit 863b688

File tree

3 files changed

+261
-49
lines changed

3 files changed

+261
-49
lines changed

README.md

Lines changed: 237 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,19 @@
44

55
## Introduction
66

7-
This repository contains the Azure SQL binding for Azure Functions extension code as well as a quick start tutorial and samples illustrating how to use the binding in different ways. A high level explanation of the bindings is provided below. Additional information for each is in their respective sample sections.
7+
This repository contains the Azure SQL bindings for Azure Functions extension code as well as a quick start tutorial and samples illustrating how to use the binding in different ways. A high level explanation of the bindings is provided below. Additional information for each is in their respective sample sections.
88

9-
- **Input Binding**: takes a SQL query to run and returns the output of the query in the function.
10-
- **Output Binding**: takes a list of rows and upserts them into the user table (i.e. If a row doesn't already exist, it is added. If it does, it is updated).
11-
- **Trigger Binding**: monitors the user table for changes (i.e., row inserts, updates, and deletes) and invokes the function with updated rows.
9+
- [**Input Binding**](#input-binding-tutorial): takes a SQL query to run and returns the output of the query in the function.
10+
- [**Output Binding**](#output-binding-tutorial): takes a list of rows and upserts them into the user table (i.e. If a row doesn't already exist, it is added. If it does, it is updated).
11+
- [**Trigger Binding**](#trigger-binding-tutorial): monitors the user table for changes (i.e., row inserts, updates, and deletes) and invokes the function with updated rows.
1212

1313
Further information on the Azure SQL binding for Azure Functions is also available in the [Azure Functions docs](https://docs.microsoft.com/azure/azure-functions/functions-bindings-azure-sql).
1414

15+
Azure SQL bindings for Azure Functions are supported for:
16+
- .NET functions (C# in-process)
17+
- NodeJS functions (JavaScript/TypeScript)
18+
- Python functions
19+
1520
## Table of Contents
1621

1722
- [Azure SQL binding for Azure Functions - Preview](#azure-sql-binding-for-azure-functions---preview)
@@ -25,9 +30,9 @@ Further information on the Azure SQL binding for Azure Functions is also availab
2530
- [Create .NET Function App](#create-net-function-app)
2631
- [Configure Function App](#configure-function-app)
2732
- [Tutorials](#tutorials)
28-
- [Input Binding Tutorial](#input-binding-tutorial)
29-
- [Output Binding Tutorial](#output-binding-tutorial)
30-
- [Trigger Binding Tutorial](#trigger-binding-tutorial)
33+
- [.NET functions](#net-functions)
34+
- [Input Binding Tutorial](#input-binding-tutorial)
35+
- [Output Binding Tutorial](#output-binding-tutorial)
3136
- [More Samples](#more-samples)
3237
- [Input Binding](#input-binding)
3338
- [Query String](#query-string)
@@ -90,17 +95,6 @@ ALTER TABLE ['{table_name}'] ALTER COLUMN ['{primary_key_column_name}'] int NOT
9095
ALTER TABLE ['{table_name}'] ADD CONSTRAINT PKey PRIMARY KEY CLUSTERED (['{primary_key_column_name}']);
9196
```
9297

93-
3. If you plan to use the trigger support, you need to enable [change tracking](https://docs.microsoft.com/sql/relational-databases/track-changes/about-change-tracking-sql-server) on the SQL database and the SQL table. Please note that enabling change tracking will add to the cost of the SQL server.
94-
95-
```sql
96-
ALTER DATABASE ['your database name']
97-
SET CHANGE_TRACKING = ON
98-
(CHANGE_RETENTION = 2 DAYS, AUTO_CLEANUP = ON);
99-
100-
ALTER TABLE ['your table name']
101-
ENABLE CHANGE_TRACKING;
102-
```
103-
10498

10599
### Create .NET Function App
106100

@@ -110,8 +104,9 @@ These steps can be done in the Terminal/CLI or with PowerShell.
110104

111105
1. Install [Azure Functions Core Tools](https://docs.microsoft.com/azure/azure-functions/functions-run-local)
112106

113-
2. Create a function app.
107+
2. Create a function app for .NET, JavaScript, TypeScript or Python.
114108

109+
**.NET**
115110
```bash
116111
mkdir MyApp
117112
cd MyApp
@@ -126,6 +121,34 @@ These steps can be done in the Terminal/CLI or with PowerShell.
126121
dotnet add package Microsoft.Azure.WebJobs.Extensions.Sql --prerelease
127122
```
128123

124+
**JavaScript and TypeScript:** Update the `host.json` file to the preview extension bundle.
125+
```json
126+
"extensionBundle": {
127+
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
128+
"version": "[4.*, 5.0.0)"
129+
}
130+
```
131+
132+
**Python:**
133+
134+
Update the `host.json` file to the preview extension bundle.
135+
```json
136+
"extensionBundle": {
137+
"id": "Microsoft.Azure.Functions.ExtensionBundle.Preview",
138+
"version": "[4.*, 5.0.0)"
139+
}
140+
```
141+
142+
Add a preview version of the Python functions library to `requirements.txt`.
143+
```txt
144+
azure-functions==1.11.3b1
145+
```
146+
147+
Add a setting in `local.settings.json` to isolate the worker dependencies.
148+
```json
149+
"PYTHON_ISOLATE_WORKER_DEPENDENCIES": "1"
150+
```
151+
129152
### Configure Function App
130153

131154
Once you have your Function App you need to configure it for use with Azure SQL bindings for Azure Functions.
@@ -178,11 +201,13 @@ Once you have your Function App you need to configure it for use with Azure SQL
178201

179202
## Tutorials
180203

181-
### Input Binding Tutorial
204+
### .NET functions
205+
206+
#### Input Binding Tutorial
182207

183208
Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](#Create-a-SQL-Server).
184209

185-
- Open your app that you created in 'Set Up Your Local Environment' in VSCode
210+
- Open your app that you created in [Create a Function App](#create-a-function-app) in VSCode
186211
- Press 'F1' and search for 'Azure Functions: Create Function'
187212
- Choose HttpTrigger -> (Provide a function name) -> Company.namespace -> anonymous
188213
- In the file that opens, replace the 'public static async Task< IActionResult > Run' block with the below code.
@@ -205,7 +230,7 @@ Note: This tutorial requires that a SQL database is setup as shown in [Create a
205230
- Add 'using System.Collections.Generic;' to the namespaces list at the top of the page.
206231
- Currently, there is an error for the IEnumerable. We'll fix this by creating an Employee class.
207232
- Create a new file and call it 'Employee.cs'
208-
- Paste the below in the file. These are the column values of our SQL Database table.
233+
- Paste the below in the file. These are the column names of our SQL table.
209234
210235
```csharp
211236
namespace Company.Function {
@@ -226,14 +251,14 @@ Note: This tutorial requires that a SQL database is setup as shown in [Create a
226251
- You should see your database output in the browser window.
227252
- Congratulations! You have successfully created your first SQL input binding! Checkout [Input Binding](#Input-Binding) for more information on how to use it and explore on your own!
228253
229-
### Output Binding Tutorial
254+
#### Output Binding Tutorial
230255
231256
Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](#Create-a-SQL-Server), and that you have the 'Employee.cs' class from the [Input Binding Tutorial](#Input-Binding-Tutorial).
232257
233258
- Open your app in VSCode
234259
- Press 'F1' and search for 'Azure Functions: Create Function'
235260
- Choose HttpTrigger -> (Provide a function name) -> Company.namespace is fine -> anonymous
236-
- In the file which opens, replace the 'public static async Task<IActionResult> Run' block with the below code
261+
- In the file that opens, replace the 'public static async Task<IActionResult> Run' block with the below code
237262
238263
```csharp
239264
public static IActionResult Run(
@@ -272,6 +297,193 @@ Note: This tutorial requires that a SQL database is setup as shown in [Create a
272297
- Hit 'F5' to run your code. Click the link to upsert the output array values in your SQL table. Your upserted values should launch in the browser.
273298
- Congratulations! You have successfully created your first SQL output binding! Checkout [Output Binding](#Output-Binding) for more information on how to use it and explore on your own!
274299
300+
301+
### JavaScript functions
302+
303+
#### Input Binding Tutorial
304+
305+
Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](#Create-a-SQL-Server).
306+
307+
- Open your app that you created in [Create a Function App](#create-a-function-app) in VSCode
308+
- Press 'F1' and search for 'Azure Functions: Create Function'
309+
- Choose HttpTrigger -> (Provide a function name) -> anonymous
310+
- In the file that opens (index.js), replace the 'module.exports = async function (context, req)' block with the below code.
311+
312+
```javascript
313+
module.exports = async function (context, req, employee) {
314+
return {
315+
status: 200,
316+
body: employee
317+
};
318+
}
319+
```
320+
321+
- We also need to add the SQL input binding for the `employee` parameter. Open the function.json file.
322+
- Paste the below in the file as an additional entry to the "bindings": [] array.
323+
324+
```json
325+
{
326+
"name": "employee",
327+
"type": "sql",
328+
"direction": "in",
329+
"commandText": "select * from Employees",
330+
"commandType": "Text",
331+
"connectionStringSetting": "SqlConnectionString"
332+
}
333+
```
334+
335+
*In the above, "select * from Employees" is the SQL script run by the input binding. The CommandType on the line below specifies whether the first line is a query or a stored procedure. On the next line, the ConnectionStringSetting specifies that the app setting that contains the SQL connection string used to connect to the database is "SqlConnectionString." For more information on this, see the [Input Binding](#Input-Binding) section*
336+
337+
- Open the local.settings.json file, and in the brackets for "Values," verify there is a 'SqlConnectionString.' If not, add it.
338+
- Hit 'F5' to run your code. This will start up the Functions Host with a local HTTP Trigger and SQL Input Binding.
339+
- Click the link that appears in your terminal.
340+
- You should see your database output in the browser window.
341+
- Congratulations! You have successfully created your first SQL input binding! Checkout [Input Binding](#Input-Binding) for more information on how to use it and explore on your own!
342+
343+
#### Output Binding Tutorial
344+
345+
Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](#Create-a-SQL-Server).
346+
347+
- Open your app in VSCode
348+
- Press 'F1' and search for 'Azure Functions: Create Function'
349+
- Choose HttpTrigger -> (Provide a function name) -> anonymous
350+
- In the file that opens (index.js), replace the 'module.exports = async function (context, req)' block with the below code.
351+
352+
```javascript
353+
module.exports = async function (context, req) {
354+
const employees = [
355+
{
356+
EmployeeId = 1,
357+
FirstName = "Hello",
358+
LastName = "World",
359+
Company = "Microsoft",
360+
Team = "Functions"
361+
},
362+
{
363+
EmployeeId = 2,
364+
FirstName = "Hi",
365+
LastName = "SQLupdate",
366+
Company = "Microsoft",
367+
Team = "Functions"
368+
}
369+
];
370+
context.bindings.employee = employees;
371+
372+
return {
373+
status: 201,
374+
body: employees
375+
};
376+
}
377+
```
378+
379+
- We also need to add the SQL output binding for the `context.bindings.employee` property. Open the function.json file.
380+
- Paste the below in the file as an additional entry to the "bindings": [] array.
381+
382+
```json
383+
{
384+
"name": "employee",
385+
"type": "sql",
386+
"direction": "out",
387+
"commandText": "dbo.Employees",
388+
"connectionStringSetting": "SqlConnectionString"
389+
}
390+
```
391+
*In the above, "dbo.Employees" is the name of the table our output binding is upserting into. The line below is similar to the input binding and specifies where our SqlConnectionString is. For more information on this, see the [Output Binding](#Output-Binding) section*
392+
393+
- Hit 'F5' to run your code. Click the link to upsert the output array values in your SQL table. Your upserted values should launch in the browser.
394+
- Congratulations! You have successfully created your first SQL output binding! Checkout [Output Binding](#Output-Binding) for more information on how to use it and explore on your own!
395+
396+
### Python functions
397+
398+
#### Input Binding Tutorial
399+
400+
Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](#Create-a-SQL-Server).
401+
402+
- Open your app that you created in [Create a Function App](#create-a-function-app) in VSCode
403+
- Press 'F1' and search for 'Azure Functions: Create Function'
404+
- Choose HttpTrigger -> (Provide a function name) -> anonymous
405+
- In the file that opens (__init__.py), replace the 'def main(req: func.HttpRequest) -> func.HttpResponse:' block with the below code.
406+
407+
```python
408+
def main(req: func.HttpRequest, employee: func.SqlRowList) -> func.HttpResponse:
409+
rows = list(map(lambda r: json.loads(r.to_json()), employee))
410+
411+
return func.HttpResponse(
412+
json.dumps(rows),
413+
status_code=200,
414+
mimetype="application/json"
415+
)
416+
```
417+
418+
- Add an import json statement to the top of the file.
419+
- We also need to add the SQL input binding for the `employee` parameter. Open the function.json file.
420+
- Paste the below in the file as an additional entry to the "bindings": [] array.
421+
422+
```json
423+
{
424+
"name": "employee",
425+
"type": "sql",
426+
"direction": "in",
427+
"commandText": "select * from Employees",
428+
"commandType": "Text",
429+
"connectionStringSetting": "SqlConnectionString"
430+
}
431+
```
432+
433+
*In the above, "select * from Employees" is the SQL script run by the input binding. The CommandType on the line below specifies whether the first line is a query or a stored procedure. On the next line, the ConnectionStringSetting specifies that the app setting that contains the SQL connection string used to connect to the database is "SqlConnectionString." For more information on this, see the [Input Binding](#Input-Binding) section*
434+
435+
- Open the local.settings.json file, and in the brackets for "Values," verify there is a 'SqlConnectionString.' If not, add it.
436+
- Hit 'F5' to run your code. This will start up the Functions Host with a local HTTP Trigger and SQL Input Binding.
437+
- Click the link that appears in your terminal.
438+
- You should see your database output in the browser window.
439+
- Congratulations! You have successfully created your first SQL input binding! Checkout [Input Binding](#Input-Binding) for more information on how to use it and explore on your own!
440+
441+
#### Output Binding Tutorial
442+
443+
Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](#Create-a-SQL-Server).
444+
445+
- Open your app in VSCode
446+
- Press 'F1' and search for 'Azure Functions: Create Function'
447+
- Choose HttpTrigger -> (Provide a function name) -> anonymous
448+
- In the file that opens (__init__.py), replace the 'def main(req: func.HttpRequest) -> func.HttpResponse:' block with the below code.
449+
450+
```python
451+
def main(req: func.HttpRequest, employee: func.Out[func.SqlRow]) -> func.HttpResponse:
452+
newEmployee = {
453+
EmployeeId = 1,
454+
FirstName = "Hello",
455+
LastName = "World",
456+
Company = "Microsoft",
457+
Team = "Functions"
458+
}
459+
row = func.SqlRow(newEmployee)
460+
employee.set(row);
461+
462+
return func.HttpResponse(
463+
body=json.dumps(newEmployee),
464+
status_code=201,
465+
mimetype="application/json"
466+
)
467+
```
468+
469+
- Add an import json statement to the top of the file.
470+
- We also need to add the SQL output binding for the `context.bindings.employee` property. Open the function.json file.
471+
- Paste the below in the file as an additional entry to the "bindings": [] array.
472+
473+
```json
474+
{
475+
"name": "employee",
476+
"type": "sql",
477+
"direction": "out",
478+
"commandText": "dbo.Employees",
479+
"connectionStringSetting": "SqlConnectionString"
480+
}
481+
```
482+
*In the above, "dbo.Employees" is the name of the table our output binding is upserting into. The line below is similar to the input binding and specifies where our SqlConnectionString is. For more information on this, see the [Output Binding](#Output-Binding) section*
483+
484+
- Hit 'F5' to run your code. Click the link to upsert the output array values in your SQL table. Your upserted values should launch in the browser.
485+
- Congratulations! You have successfully created your first SQL output binding! Checkout [Output Binding](#Output-Binding) for more information on how to use it and explore on your own!
486+
275487
### Trigger Binding Tutorial
276488
277489
Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](#create-a-sql-server), and that you have the 'Employee.cs' file from the [Input Binding Tutorial](#input-binding-tutorial).
@@ -619,7 +831,7 @@ The trigger binding can bind to type `IReadOnlyList<SqlChange<T>>`:
619831
620832
- **IReadOnlyList<SqlChange\<T\>>**: If there are multiple rows updated in the SQL table, the user function will get invoked with a batch of changes, where each element is a `SqlChange` object. Here `T` is a generic type-argument that can be substituted with a user-defined POCO, or Plain Old C# Object, representing the user table row. The POCO should therefore follow the schema of the queried table. See the [Query String](#query-string) section for an example of what the POCO should look like. The two properties of class `SqlChange<T>` are `Item` of type `T` which represents the table row and `Operation` of type `SqlChangeOperation` which indicates the kind of row operation (insert, update, or delete) that triggered the user function.
621833
622-
Note that for insert and update operations, the user function receives POCO object containing the latest values of table columns. For delete operation, only the properties corresponding to the primary keys of the row are populated.
834+
Note that for insert and update operations, the user function receives POCO object containing the latest values of table columns. For delete operation, only the properties corresponding to the primary keys of the row are populated.
623835
624836
Any time when the changes happen to the "Products" table, the user function will be invoked with a batch of changes. The changes are processed sequentially, so if there are a large number of changes pending to be processed, the function will be passed a batch containing the earliest changes first.
625837

0 commit comments

Comments
 (0)