---
metadata:
  - name: generator
    content: Diplodoc Platform v5.39.1
alternate:
  - https://yandex.com.tr/support/forms/en/visualize-datalens.md
---
> **Documentation Index:** Fetch the complete configuration index at https://yandex.com.tr/support/forms/en/llms.txt

# Visualizing data in DataLens using Cloud Functions

You can deliver form responses to a PostgreSQL database created in Yandex Cloud and visualize them in DataLens.

With this guide, you will learn how to visualize:
* Number of form responses grouped by date.
* Statistics on answers to **Short text** and **One option** type questions, grouped by date.

## Step 1. Create a database

1. Go to the [Yandex Cloud management console](https://console.cloud.yandex.com) and select the folder where you want to create a database.
1. In the left-hand panel, click <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M9.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9.5 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm5 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM13 4.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM4.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM8 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm6.5-1.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" clip-rule="evenodd"/></svg> and select Managed Service for PostgreSQL.
1. In the top-right corner, click **Create cluster**.
1. Configure the cluster:
	1. Under **Basic parameters**, fill in the **Cluster name** field. The name may contain uppercase and lowercase Latin letters, numbers, underscores, and hyphens.
	1. Under **Database**, fill in the **DB name** and **Username** fields. The names may contain uppercase and lowercase Latin letters, numbers, underscores, and hyphens.
	1. Under **Database**, fill in the **Password** field.
	1. Under **Database**, set the **Locale for sorting (LC_COLLATE)** and **Charset locale (LC_CTYPE)** fields to **en_US.UTF8**. Once you create a database, you cannot change these parameters.
	1. Under **Additional settings**, enable **Access from the management console**, **Serverless access**, and **DataLens access**.
	1. Configure other parameters if needed. For more information, see [{#T}](https://yandex.cloud/en/docs/managed-postgresql/operations/cluster-create).
1. Click **Create cluster**.
1. Wait until the new cluster's **Availability** field changes to **Alive**.

## Step 2. Create tables

1. Go to the page of the created cluster.
1. In the left-hand panel, click **SQL**.
1. Select the appropriate username and database, enter the password, and click **Connect**.
1. Select the **public** schema.
1. Run the following SQL queries to create the following tables:
	1. Table to store all form responses:
		```sql
		create table answers(
			id serial primary key,
			answer jsonb,
			created timestamp with time zone default now()
		);
		```
	1. Table to count the number of form responses:
		```sql
		create table answercount(
  			id serial primary key,
  			survey_id text not null,
  			modified date not null default current_date,
  			count int default 0,
  			unique(survey_id, modified)
		);
		```
	1. Table for storing answers to **Short text** and **One option** type questions:
		```sql
		create table questioncount(
  			id serial primary key,
			survey_id text not null,
			question_key text not null,
			option_key text not null default '',
			modified date not null default current_date,
			count int default 0,
			unique(survey_id, question_key, option_key, modified)
		);
		```

## Step 3. Create a connection to the database

1. In the [management console](https://console.cloud.yandex.com), return to the folder with the new cluster.
1. In the left-hand panel, click <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M9.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9.5 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm5 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM13 4.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM4.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM8 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm6.5-1.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" clip-rule="evenodd"/></svg> and select Cloud Functions.
1. In the left-hand panel, click <svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" fill="currentColor" aria-hidden="true" class="yc-icon nv-composite-bar__menu-icon"><svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 16 16"><g clip-path="url(#svg-5tn4g3mg__a)"><path fill="currentColor" fill-rule="evenodd" d="M14.5 12.75a2.75 2.75 0 0 0-2-2.646V8.75h2.25a.75.75 0 0 0 0-1.5h-6V5.896a2.752 2.752 0 0 0 2-2.646 2.75 2.75 0 1 0-3.5 2.646V7.25h-6a.75.75 0 0 0 0 1.5H3.5v1.354a2.752 2.752 0 0 0-2 2.646A2.75 2.75 0 1 0 5 10.104V8.75h6v1.354a2.751 2.751 0 1 0 3.5 2.646ZM11.75 14a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5ZM8 4.5A1.25 1.25 0 1 0 8 2a1.25 1.25 0 0 0 0 2.5ZM4.25 14a1.25 1.25 0 1 0 0-2.5 1.25 1.25 0 0 0 0 2.5Z" clip-rule="evenodd"/></g><defs><clipPath id="svg-5tn4g3mg__a"><path fill="currentColor" d="M0 0h16v16H0z"/></clipPath></defs></svg></svg>.
1. In the top-right corner, click **Create connection**.
1. Set up a connection:
	1. Fill in the **Name** field. The name may only contain lowercase Latin letters, numbers, and hyphens.
	1. In the **Type** field, select **PostgreSQL**.
	1. Fill in the **Cluster**, **Database**, **User**, and **Password** fields. Enter the same field values as you set when creating your cluster in step 1.
1. Tap **Create**.
1. Go to the connection page and copy the **Entry point** field value.

## Step 4. Create a service account

1. In the [management console](https://console.cloud.yandex.com), return to the folder with the new cluster.
1. In the top-right corner, click <svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" fill="currentColor" aria-hidden="true" class="yc-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill-rule="evenodd" d="M14 6.125a1.874 1.874 0 1 1 .001 3.749A1.874 1.874 0 0 1 14 6.125zm-5.906 0a1.874 1.874 0 1 1 0 3.749 1.874 1.874 0 0 1 0-3.749zM2 6.125a1.874 1.874 0 1 1 .001 3.749A1.874 1.874 0 0 1 2 6.125z"/></svg></svg> → **Create service account**.
1. In the service account creation window, fill in the following fields:
	1. **Name**; it may only contain lowercase Latin letters, numbers, and hyphens.
	1. **Description**; it may contain any characters.
	1. In the **Roles in folder** field, add the following roles:
		* `serverless.functions.invoker`
		* `serverless.mdbProxies.user`
1. Tap **Create**.

## Step 5. Create a service account key

1. In the [management console](https://console.cloud.yandex.com), return to the folder with the new cluster.
1. Go to the **Service accounts** tab.
1. Select the account you need.
1. In the top panel on the account page, click **Create new key** → **Create API key**.
1. Provide a brief description for the key.
1. Tap **Create**.
1. This will open a window with the key ID and the secret key. Store them in a secure place. You will not be able to access them after you close the window.

## Step 6. Create a cloud function

1. In the [management console](https://console.cloud.yandex.com), return to the folder with the new cluster.

1. In the left-hand panel, click <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M9.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9.5 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm5 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM13 4.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM4.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM8 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm6.5-1.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" clip-rule="evenodd"/></svg> and select Cloud Functions.

1. In the top-right corner, click **Create function**.

1. On the function creation page, fill in the following fields:
	1. **Name**; it may only contain lowercase Latin letters, numbers, and hyphens.
	1. **Description**; it may contain any characters.

1. Select the Python programming language.

1. Create a file named `requirements.txt` and add the following line to it:
	```
	psycopg2
	```

1. Create or edit a file named `index.py`:
	
	```python
	import json
	import psycopg2

	def get_connection(context):
		return psycopg2.connect(
			database="<connection_ID>",
			user="<username>",
			password=context.token["access_token"],
			host="<entry_point>",
			port=6432,
			sslmode="require",
		)

	def run_function(connection, answer, **params):
		survey_id = answer['survey']['id']
		args = (survey_id, )

		with connection.cursor() as c:
			sql = '''
				insert into answercount as t (survey_id, count) 
				values(%s, 1)
				on conflict (survey_id, modified) 
				do update set count = t.count + excluded.count
			'''
			c.execute(sql, args)

		args, args_size = [], 0
		for question_key, question_data in answer['data'].items():
			match question_data['question']['answer_type']['slug']:
				case 'answer_choices':
					for choice_item in question_data['value']:
						args.extend([survey_id, question_key, choice_item['key']])
						args_size += 1
				case 'answer_short_text':
					args.extend([survey_id, question_key, ''])
					args_size += 1

		with connection.cursor() as c:
			values = ','.join(['(%s, %s, %s, 1)'] * args_size)
			sql = '''
				insert into questioncount as t (survey_id, question_key, option_key, count) 
				values{values}
				on conflict (survey_id, question_key, option_key, modified) 
				do update set count = t.count + excluded.count
			'''.format(values=values)
			c.execute(sql, args)
			
		connection.commit()
	
	def handler(event, context):
    	body = json.loads(event.get('body'))
		params ={
			name: value
			for name, value in body.items()
			if name != 'answer'
		}
		connection = get_connection(context)
		result ={
			'id': run_function(connection, body.get('answer'), **params),
		}

		return{
			'statusCode': 200,
			'body': result,
			'headers':{
				'Content-Type': 'application/json',
			}
		}
	```
	
	Substitute the following values in this function:
	* `<connection_ID>`: Value of the **ID** field of the database connection you created in step 3. You can copy it on the connection page.
	* `<username>`: Database user name that you specified in the cluster settings in step 1. You can find it in the **Users** tab on the cluster page.
	* `<entry_point>`: Value of the **Entry point** field of the database connection you created in step 3. You can copy it on the connection page.

1. Click **Save changes**.

1. On the function page, copy the value from the **ID** field.

## Step 7. Set up integration

1. Go to the form whose responses you want to deliver to the database and select the **Integrations** tab.
1. Select a group of actions to set up issue creation in and click Cloud Functions at the bottom of the group.
1. In the **Function code** field, paste the function ID that you copied in the previous step.
1. Under **Parameters**, you can optionally select additional parameters to be transferred to the function.
1. Click **Save**.

## Step 8. Connect DataLens to the database

1. In the [management console](https://console.cloud.yandex.com), return to the folder with the new cluster.
1. In the left-hand panel, click <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><path fill="currentColor" fill-rule="evenodd" d="M9.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 9.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM9.5 8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0Zm5 0a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM13 4.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3ZM4.5 3a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM8 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Zm6.5-1.5a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM3 14.5a1.5 1.5 0 1 0 0-3 1.5 1.5 0 0 0 0 3Z" clip-rule="evenodd"/></svg> and select DataLens.
1. Click **Create connection** → **PostgreSQL**.
1. Set up a connection:
	1. In the **Cloud and folder** field, select the folder where you created the cluster.
	1. In the **Cluster** field, select the cluster that you created in step 1.
	1. In the **Host name** field, select a host.
	1. In the **Path to database** field, select the database where you created tables in step 2.
	1. In the **User** field, select the user that you created along with the cluster in step 1.
	1. In the **Password** field, enter the password that you created in step 1.
1. Click **Create connection**.

## Step 9. Create a chart

1. In the top-right corner, click **Create dataset**.
1. Drag the `public.answercount` table to the area in the middle of the page.
1. In the top-right corner, click **Create chart**.
1. Drag the table column names from the **Dimensions** section to the **Bar chart** panel as follows:
	* `modified` to the **X** field
	* `count` to the **Y** field
	* `survey_id` to the **Filters** field
1. Click **Save**.

## Step 10. Create a dashboard

1. Go back to the DataLens page.
1. Click **Create dashboard**.
1. Select the folder where you want to create your dashboard, name it, and click **Create**.
1. In the top panel, click **Add** → **Chart**.
1. In the add chart window:
	1. Fill in the **Name** field.
	1. In the **Chart** field, select the chart that you created in step 9.
	1. Click **Add**.
1. In the top-right corner, click **Save**.

You will get a bar chart with the number of form responses by date.

## Step 11. Set up the chart

1. Go to the page of the cluster that you created in step 1.
1. In the left-hand panel, click **SQL**.
1. Select the appropriate username and database, enter the password, and click **Connect**.
1. Select the **public** schema.
1. Run the following SQL query:
	1. Create a table that will store the information about chart colors:
		```sql
		create table labels(
			id serial primary key,
			compound_key text not null,
			label text default '',
			unique(compound_key)
		);
		```
	1. Add information about labels for answer options to this table:
		```sql
		insert into labels(compound_key, label)
		values('id-radio.62019338', 'Option 1'), ('id-radio.62019364', 'Option 2'), ('id-radio.62019365', 'Option 3');
		```
	1. Create a view with a link between question IDs and answer option IDs.
		```sql
		create view questioncount_vw as
		select t.*, 
			case 
				when t.option_key = '' or t.option_key is null then t.question_key
				else t.question_key || '.' || t.option_key
			end as compound_key
		from questioncount t;
		```

## Step 12. Set up display of colors in the chart 

1. Open the DataLens page and go to the connection that you created in step 8.
1. In the top-right corner, click **Create dataset**.
1. Drag the `public.questioncount_vw` table to the middle of the page.
1. Drag the `public.labels` table to the middle of the page.
1. Click ![](_assets/datalens-inner-join.png =16x) between the table names in the middle of the page.
1. In the window that opens, click ![](_assets/datalens-inner-join.png =16x) once again, select the **left** value by the `compound key` field, and click **Save**.
1. Go to the **Fields** tab.
1. In the top panel, click **Add field**.
1. Fill in the fields of the field creation window:
	1. In **Field name**, enter `question_label`.
	1. In the main part of the field, enter:
		```
		if [label] is not null then [label] else [compound key (1)] end
		```
	1. Click **Save**.
1. In the top panel, click **Create chart**.
Drag the names from the **Dimensions** section to the **Bar chart** panel as follows:
	* `modified` to the **X** field
	* `count` to the **Y** field
	* `question_label` to the **Colors** field
	* `survey_id` and `question_key` to the **Filters** field
1. Click **Save**.

## Step 13. Place the new chart on the dashboard

1. Go to the dashboard that you created in step 10.
1. In the top panel, click **Add** → **Chart**.
1. In the add chart window:
	1. Fill in the **Name** field.
	1. In the **Chart** field, select the chart that you created in step 12.
	1. Click **Add**.
1. In the top-right corner, click **Save**.

Now, your dashboard contains two similar bar charts, single- and multicolor, whose colors depend on user responses.

## Step 14. Set up dashboard auto-update

1. In the top panel, click <svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="none" viewBox="0 0 16 16"><g clip-path="url(#svg-uv9o9m4o__a)"><path fill="currentColor" fill-rule="evenodd" d="M7.199 2H8.8a.2.2 0 0 1 .2.2c0 1.808 1.958 2.939 3.524 2.034a.199.199 0 0 1 .271.073l.802 1.388a.199.199 0 0 1-.073.272c-1.566.904-1.566 3.164 0 4.069a.199.199 0 0 1 .073.271l-.802 1.388a.199.199 0 0 1-.271.073C10.958 10.863 9 11.993 9 13.8a.2.2 0 0 1-.199.2H7.2a.199.199 0 0 1-.2-.2c0-1.808-1.958-2.938-3.524-2.034a.199.199 0 0 1-.272-.073l-.8-1.388a.199.199 0 0 1 .072-.271c1.566-.905 1.566-3.165 0-4.07a.199.199 0 0 1-.073-.271l.801-1.388a.199.199 0 0 1 .272-.073C5.042 5.138 7 4.007 7 2.2c0-.11.089-.199.199-.199ZM5.5 2.2c0-.94.76-1.7 1.699-1.7H8.8c.94 0 1.7.76 1.7 1.7a.85.85 0 0 0 1.274.735 1.699 1.699 0 0 1 2.32.622l.802 1.388c.469.813.19 1.851-.622 2.32a.85.85 0 0 0 0 1.472 1.7 1.7 0 0 1 .622 2.32l-.802 1.388a1.699 1.699 0 0 1-2.32.622.85.85 0 0 0-1.274.735c0 .939-.76 1.7-1.699 1.7H7.2a1.7 1.7 0 0 1-1.699-1.7.85.85 0 0 0-1.274-.735 1.698 1.698 0 0 1-2.32-.622l-.802-1.388a1.699 1.699 0 0 1 .622-2.32.85.85 0 0 0 0-1.471 1.699 1.699 0 0 1-.622-2.321l.801-1.388a1.699 1.699 0 0 1 2.32-.622A.85.85 0 0 0 5.5 2.2Zm4 5.8a1.5 1.5 0 1 1-3 0 1.5 1.5 0 0 1 3 0ZM11 8a3 3 0 1 1-6 0 3 3 0 0 1 6 0Z" clip-rule="evenodd"/></g><defs><clipPath id="svg-uv9o9m4o__a"><path fill="currentColor" d="M0 0h16v16H0z"/></clipPath></defs></svg>.
1. In the window that opens, select **Auto-update** and set the interval between dashboard updates.
1. Click **Save**.

{% include [style](https://yandex.com.tr/support/forms/en/_assets/style-a13ddc9841bc.md) %}
