From 5c1e2a7eb851567654a0e4d5010afc7d06ecc027 Mon Sep 17 00:00:00 2001 From: Lucy Zhang Date: Thu, 9 Feb 2023 17:08:32 -0800 Subject: [PATCH 1/3] update python setup doc --- docs/SetupGuide_Python.md | 32 +++++++------------ .../samples-python/GetProducts/__init__.py | 4 +++ .../GetProductsNameEmpty/__init__.py | 1 + .../GetProductsNameNull/__init__.py | 17 ++++++++++ .../GetProductsNameNull/function.json | 29 +++++++++++++++++ .../GetProductsStoredProcedure/__init__.py | 3 ++ 6 files changed, 65 insertions(+), 21 deletions(-) create mode 100644 samples/samples-python/GetProductsNameNull/__init__.py create mode 100644 samples/samples-python/GetProductsNameNull/function.json diff --git a/docs/SetupGuide_Python.md b/docs/SetupGuide_Python.md index 602c8961c..b6af82f35 100644 --- a/docs/SetupGuide_Python.md +++ b/docs/SetupGuide_Python.md @@ -13,23 +13,21 @@ - [Empty Parameter Value](#empty-parameter-value) - [Null Parameter Value](#null-parameter-value) - [Stored Procedure](#stored-procedure) - - [IAsyncEnumerable](#iasyncenumerable) - [Output Binding](#output-binding) - [function.json Properties for Output Bindings](#functionjson-properties-for-output-bindings) - [Setup for Output Bindings](#setup-for-output-bindings) - [Samples for Output Bindings](#samples-for-output-bindings) - - [ICollector\/IAsyncCollector\](#icollectortiasynccollectort) - [Array](#array) - [Single Row](#single-row) - [Trigger Binding](#trigger-binding) -## Setup Function App +## Setup Function Project -These instructions will guide you through creating your Function App and adding the SQL binding extension. This only needs to be done once for every function app you create. If you have one created already you can skip this step. +These instructions will guide you through creating your Function Project and adding the SQL binding extension. This only needs to be done once for every function project you create. If you have one created already you can skip this step. 1. Install [Azure Functions Core Tools](https://docs.microsoft.com/azure/azure-functions/functions-run-local) -2. Create a function app for Python: +2. Create a function project for Python: *See [#250](https://github.com/Azure/azure-functions-sql-extension/issues/250) before starting.* ```bash @@ -38,7 +36,7 @@ These instructions will guide you through creating your Function App and adding func init --worker-runtime python ``` -3. Enable SQL bindings on the function app. More information can be found in the [Azure SQL bindings for Azure Functions docs](https://aka.ms/sqlbindings). +3. Enable SQL bindings on the function project. More information can be found in the [Azure SQL bindings for Azure Functions docs](https://aka.ms/sqlbindings). Update the `host.json` file to the preview extension bundle. @@ -69,7 +67,7 @@ See [Input Binding Overview](./BindingsOverview.md#input-binding) for general in Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](./GeneralSetup.md#create-a-sql-server). -- Open your app that you created in [Create a Function App](./GeneralSetup.md#create-a-function-app) in VS Code +- Open your project that you created in [Create a Function Project](./GeneralSetup.md#create-a-function-project) in VS Code - Press 'F1' and search for 'Azure Functions: Create Function' - Choose HttpTrigger -> (Provide a function name) -> anonymous - In the file that opens (`__init__.py`), replace the generated function with the following @@ -115,23 +113,19 @@ Note: This tutorial requires that a SQL database is setup as shown in [Create a #### Query String -_TODO_ +See the [GetProducts](https://github.com/Azure/azure-functions-sql-extension/tree/main/samples/samples-python/GetProducts) sample #### Empty Parameter Value -_TODO_ +See the [GetProductsNameEmpty](https://github.com/Azure/azure-functions-sql-extension/tree/main/samples/samples-python/GetProductsNameEmpty) sample #### Null Parameter Value -_TODO_ +See the [GetProductsNameNull](https://github.com/Azure/azure-functions-sql-extension/tree/main/samples/samples-python/GetProductsNameNull) sample #### Stored Procedure -_TODO_ - -#### IAsyncEnumerable - -_TODO_ +See the [GetProductsStoredProcedure](https://github.com/Azure/azure-functions-sql-extension/tree/main/samples/samples-python/GetProductsStoredProcedure) sample ## Output Binding @@ -198,17 +192,13 @@ Note: This tutorial requires that a SQL database is setup as shown in [Create a ### Samples for Output Bindings -#### ICollector<T>/IAsyncCollector<T> - -_TODO_ - #### Array -_TODO_ +See the [AddProductsArray](https://github.com/Azure/azure-functions-sql-extension/tree/main/samples/samples-python/AddProductsArray) sample #### Single Row -_TODO_ +See the [AddProduct](https://github.com/Azure/azure-functions-sql-extension/tree/main/samples/samples-python/AddProduct) sample ## Trigger Binding diff --git a/samples/samples-python/GetProducts/__init__.py b/samples/samples-python/GetProducts/__init__.py index b87950e4f..f0b26e4ba 100644 --- a/samples/samples-python/GetProducts/__init__.py +++ b/samples/samples-python/GetProducts/__init__.py @@ -4,6 +4,10 @@ import json import azure.functions as func +# The input binding executes the `SELECT * FROM Products WHERE Cost = @Cost` query. +# The Parameters argument passes the `{cost}` specified in the URL that triggers the function, +# `getproducts/{cost}`, as the value of the `@Cost` parameter in the query. +# CommandType is set to `Text`, since the constructor argument of the binding is a raw query. def main(req: func.HttpRequest, products: func.SqlRowList) -> func.HttpResponse: rows = list(map(lambda r: json.loads(r.to_json()), products)) diff --git a/samples/samples-python/GetProductsNameEmpty/__init__.py b/samples/samples-python/GetProductsNameEmpty/__init__.py index b87950e4f..64422097b 100644 --- a/samples/samples-python/GetProductsNameEmpty/__init__.py +++ b/samples/samples-python/GetProductsNameEmpty/__init__.py @@ -4,6 +4,7 @@ import json import azure.functions as func +# The parameter value of the `@Name` parameter is an empty string. def main(req: func.HttpRequest, products: func.SqlRowList) -> func.HttpResponse: rows = list(map(lambda r: json.loads(r.to_json()), products)) diff --git a/samples/samples-python/GetProductsNameNull/__init__.py b/samples/samples-python/GetProductsNameNull/__init__.py new file mode 100644 index 000000000..9d06b5530 --- /dev/null +++ b/samples/samples-python/GetProductsNameNull/__init__.py @@ -0,0 +1,17 @@ +# Copyright (c) Microsoft Corporation. All rights reserved. +# Licensed under the MIT License. + +import json +import azure.functions as func + +# If the `{name}` specified in the `getproducts-namenull/{name}` URL is "null", the +# query returns all rows for which the Name column is `NULL`. Otherwise, it returns +# all rows for which the value of the Name column matches the string passed in `{name}` +def main(req: func.HttpRequest, products: func.SqlRowList) -> func.HttpResponse: + rows = list(map(lambda r: json.loads(r.to_json()), products)) + + return func.HttpResponse( + json.dumps(rows), + status_code=200, + mimetype="application/json" + ) diff --git a/samples/samples-python/GetProductsNameNull/function.json b/samples/samples-python/GetProductsNameNull/function.json new file mode 100644 index 000000000..41258c3e9 --- /dev/null +++ b/samples/samples-python/GetProductsNameNull/function.json @@ -0,0 +1,29 @@ +{ + "bindings": [ + { + "authLevel": "function", + "name": "req", + "type": "httpTrigger", + "direction": "in", + "methods": [ + "get" + ], + "route":"getproducts-namenull/{name}" + }, + { + "name": "$return", + "type": "http", + "direction": "out" + }, + { + "name": "products", + "type": "sql", + "direction": "in", + "commandText": "if @Name is null select * from Products where Name is null else select * from Products where @Name = name", + "commandType": "Text", + "parameters": "@Name={name}", + "connectionStringSetting": "SqlConnectionString" + } + ], + "disabled": false + } \ No newline at end of file diff --git a/samples/samples-python/GetProductsStoredProcedure/__init__.py b/samples/samples-python/GetProductsStoredProcedure/__init__.py index b87950e4f..288de07e0 100644 --- a/samples/samples-python/GetProductsStoredProcedure/__init__.py +++ b/samples/samples-python/GetProductsStoredProcedure/__init__.py @@ -4,6 +4,9 @@ import json import azure.functions as func +# `SelectProductsCost` is the name of a procedure stored in the user's database. +# The CommandType is `StoredProcedure`. The parameter value of the `@Cost` parameter in the +# procedure is once again the `{cost}` specified in the `getproducts-storedprocedure/{cost}` URL. def main(req: func.HttpRequest, products: func.SqlRowList) -> func.HttpResponse: rows = list(map(lambda r: json.loads(r.to_json()), products)) From 9dddb1e1a4e4d6b2e6504d67d71c31f55e68cde6 Mon Sep 17 00:00:00 2001 From: Lucy Zhang Date: Thu, 9 Feb 2023 17:17:28 -0800 Subject: [PATCH 2/3] update comment --- samples/samples-python/GetProductsStoredProcedure/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/samples/samples-python/GetProductsStoredProcedure/__init__.py b/samples/samples-python/GetProductsStoredProcedure/__init__.py index 288de07e0..8661646f0 100644 --- a/samples/samples-python/GetProductsStoredProcedure/__init__.py +++ b/samples/samples-python/GetProductsStoredProcedure/__init__.py @@ -6,7 +6,7 @@ # `SelectProductsCost` is the name of a procedure stored in the user's database. # The CommandType is `StoredProcedure`. The parameter value of the `@Cost` parameter in the -# procedure is once again the `{cost}` specified in the `getproducts-storedprocedure/{cost}` URL. +# procedure is the `{cost}` specified in the `getproducts-storedprocedure/{cost}` URL. def main(req: func.HttpRequest, products: func.SqlRowList) -> func.HttpResponse: rows = list(map(lambda r: json.loads(r.to_json()), products)) From 12ac55617abdde9459d6a5e6d92ec5acc2dbcbec Mon Sep 17 00:00:00 2001 From: Lucy Zhang Date: Fri, 10 Feb 2023 08:13:06 -0800 Subject: [PATCH 3/3] fix toc --- docs/SetupGuide_Python.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/SetupGuide_Python.md b/docs/SetupGuide_Python.md index b6af82f35..b631d9ed7 100644 --- a/docs/SetupGuide_Python.md +++ b/docs/SetupGuide_Python.md @@ -4,7 +4,7 @@ - [Azure SQL bindings for Azure Functions - Python](#azure-sql-bindings-for-azure-functions---python) - [Table of Contents](#table-of-contents) - - [Setup Function App](#setup-function-app) + - [Setup Function Project](#setup-function-project) - [Input Binding](#input-binding) - [function.json Properties for Input Bindings](#functionjson-properties-for-input-bindings) - [Setup for Input Bindings](#setup-for-input-bindings) @@ -147,7 +147,7 @@ The following table explains the binding configuration properties that you set i Note: This tutorial requires that a SQL database is setup as shown in [Create a SQL Server](./GeneralSetup.md#create-a-sql-server). -- Open your app in VS Code +- Open your project in VS Code - Press 'F1' and search for 'Azure Functions: Create Function' - Choose HttpTrigger -> (Provide a function name) -> anonymous - In the file that opens (`__init__.py`), replace the `def main(req: func.HttpRequest) -> func.HttpResponse:` block with the below code. Note that the casing of the Object field names and the table column names must match.