Example: Build a form that writes to Snowflake

This example walks you through building a Streamlit in Snowflake app that collects user input through a form and writes it to a Snowflake table. The app also reads the data back to display all submissions, and uses st.user to track who submitted each entry.

The app uses a container runtime. Before you begin, make sure you’ve completed the prerequisites.

Set up the target table

This example uses a database called crud_demo. You can substitute any database and schema you have access to – just update the references in the SQL and app code to match.

Create a table to store form submissions. Run the following SQL in a worksheet or SQL session:

CREATE OR REPLACE TABLE crud_demo.public.feedback (
   submitted_at TIMESTAMP_NTZ DEFAULT CURRENT_TIMESTAMP(),
   submitted_by VARCHAR,
   category VARCHAR,
   rating INTEGER,
   comments VARCHAR
);

Write the app code

On your local machine, create a file named streamlit_app.py with the following code. If you plan to use Snowsight, you can paste this code into the editor after creating the app.

import streamlit as st

st.title("Feedback Form")
st.write(f"Logged in as: {st.user.user_name}")

conn = st.connection("snowflake")
session = conn.session()

with st.form("feedback_form"):
    category = st.selectbox(
        "Category", ["Bug Report", "Feature Request", "General Feedback"]
    )
    rating = st.slider("Rating", 1, 5, 3)
    comments = st.text_area("Comments")
    submitted = st.form_submit_button("Submit")

if submitted:
    session.sql(
        """
        INSERT INTO crud_demo.public.feedback
            (submitted_by, category, rating, comments)
        VALUES (?, ?, ?, ?)
        """,
        params=[st.user.user_name, category, rating, comments],
    ).collect()
    st.success("Feedback submitted!")

st.subheader("Last 10 submissions")
data = session.sql(
    "SELECT * FROM crud_demo.public.feedback ORDER BY submitted_at DESC LIMIT 10"
).to_pandas()
st.dataframe(data, use_container_width=True)

This app uses:

  • st.form to collect input before submitting, preventing re-runs on every widget interaction.

  • st.connection("snowflake").session() to get a Snowpark session for writing data. For more information, see Manage secrets and configure your Streamlit app.

  • session.sql() instead of conn.query() to read back the submissions. conn.query() caches results by default, so new entries wouldn’t appear until the cache expires. session.sql() executes a fresh query on every rerun.

  • st.user.user_name to record who submitted each entry. For more information, see Personalize your Streamlit app with user information.

Declare dependencies

This app only uses streamlit and the built-in Snowflake connection, so no additional dependencies are required.

For more information, see Manage dependencies for your Streamlit app.

Deploy the app

  1. Sign in to Snowsight.

  2. In the navigation menu, select Projects » Streamlit.

  3. Select + Streamlit App.

  4. Enter feedback_app as the app name.

  5. Select a database and schema.

  6. Select Run on container, then select a compute pool and query warehouse.

  7. Select Create.

  8. In the editor, replace the starter code with the app code above.

  9. Select Run.

Try the app

  1. Open the app in your browser.

  2. Fill in the form fields and select Submit.

  3. The feedback table below the form updates to show your new submission, including your email address and a timestamp.

  4. Submit a few more entries, then try filtering or sorting the data in the table.

Extend the app

Try adding a delete button next to each row, or a chart that shows the average rating by category. For example, add the following after the dataframe:

import plotly.express as px

if not data.empty:
    avg_ratings = data.groupby("CATEGORY")["RATING"].mean().reset_index()
    fig = px.bar(avg_ratings, x="CATEGORY", y="RATING", title="Average Rating by Category")
    st.plotly_chart(fig, use_container_width=True)

If you add plotly, declare it in a requirements.txt file:

plotly

For more complex dependency scenarios, you can use a pyproject.toml file instead. For more information, see Manage dependencies for your Streamlit app.

Clean up

To remove the resources created in this example, run the following SQL:

DROP STREAMLIT IF EXISTS crud_demo.public.feedback_app;
DROP TABLE IF EXISTS crud_demo.public.feedback;

What’s next?