Быстрый старт: быстрое прототипирование с драйвером mssql-python под Python

В этом кратком руководстве вы Streamlit быстро создаёте отчёт, чтобы заранее собирать отзывы пользователей. Вы используете драйвер mssql-python для Python, чтобы подключиться к базе данных и считывать данные в отчет.

Драйвер mssql-python не требует внешних зависимостей на компьютерах Windows. Драйвер устанавливает все, что требуется с одной pip установкой, что позволяет использовать самую последнюю версию драйвера в новых сценариях без нарушения работы других сценариев, для обновления и тестирования которых у вас нет времени.

Документация | Исходный код mssql-python | Пакет (PyPI) | uv

Предпосылки

Установите необходимые компоненты для операционной системы

Установите единовременные предварительные условия для операционной системы. Пользователи Windows могут пропустить этот шаг. Для полной информации о платформе см. Установить mssql-python.

apk add libtool krb5-libs krb5-dev libstdc++

Создание базы данных SQL

Создайте или подключитесь к SQL-базе данных на одной из следующих платформ:

Создание проекта и запуск кода

Создание нового проекта

  1. Откройте командную строку в каталоге разработки. Если у вас его нет, создайте новую директорию, например python или scripts. Избегайте папок на OneDrive, так как синхронизация может мешать управлению виртуальной средой.

  2. Создайте новый проект с uv.

    uv init rapid-prototyping-qs
    cd rapid-prototyping-qs
    

Добавление зависимостей

В том же каталоге установите mssql-pythonи streamlitpython-dotenv пакеты.

uv add mssql-python python-dotenv streamlit

Запустите Visual Studio Code.

В том же каталоге выполните следующую команду.

code .

Обновление pyproject.toml

  1. Откройте файл в редакторе pyproject.toml . Этот файл содержит метаданные вашего проекта.

  2. Обновите значение description.

    description = "A quick example of rapid prototyping using the mssql-python driver and Streamlit."
    
  3. Сохраните и закройте файл.

Обновление main.py

  1. Откройте файл с именем main.py. Он должен быть похож на этот пример.

    def main():
        print("Hello from rapid-prototyping-qs!")
    
    if __name__ == "__main__":
        main()
    
  2. В верхней части файла добавьте следующие импорты перед строкой с def main().

    Подсказка

    Если в Visual Studio Code возникли проблемы с разрешением пакетов, необходимо обновить интерпретатор для использования виртуальной среды.

    from os import getenv
    from dotenv import load_dotenv
    from mssql_python import connect, Connection
    import pandas as pd
    import streamlit as st
    
  3. Между импортом и строкой с def main(), добавьте следующий код.

    def page_load() -> None:
        st.set_page_config(
            page_title="View Data",
            page_icon=":bar_chart:",
            layout="wide",
            initial_sidebar_state="expanded"
        )
    
        st.title("AdventureWorksLT Customer Order History")
    
        SQL_QUERY = """
        SELECT c.*
        FROM SalesLT.Customer AS c
        INNER JOIN SalesLT.SalesOrderHeader AS soh
            ON c.CustomerID = soh.CustomerID;
        """
    
        df = load_data(SQL_QUERY)
    
        event = st.dataframe(
            df,
            use_container_width=True,
            hide_index=True,
            on_select="rerun",
            selection_mode="single-row"
        )
    
        customer = event.selection.rows
    
        SPEND_QUERY_ALL = """
        SELECT
            soh.OrderDate,
            SUM(sod.OrderQty),
            SUM(sod.OrderQty * sod.UnitPrice) AS spend,
            pc.Name AS ProductCategory
        FROM SalesLT.SalesOrderDetail AS sod
        INNER JOIN SalesLT.SalesOrderHeader AS soh
            ON sod.SalesOrderID = soh.SalesOrderID
        INNER JOIN SalesLT.Product AS p
            ON sod.ProductID = p.ProductID
        INNER JOIN SalesLT.ProductCategory AS pc
            ON p.ProductCategoryID = pc.ProductCategoryID
        GROUP BY soh.OrderDate, pc.Name
        ORDER BY soh.OrderDate, pc.Name;
        """
        SPEND_QUERY_CUSTOMER = """
        SELECT
            soh.OrderDate,
            SUM(sod.OrderQty),
            SUM(sod.OrderQty * sod.UnitPrice) AS spend,
            pc.Name AS ProductCategory
        FROM SalesLT.SalesOrderDetail AS sod
        INNER JOIN SalesLT.SalesOrderHeader AS soh
            ON sod.SalesOrderID = soh.SalesOrderID
        INNER JOIN SalesLT.Product AS p
            ON sod.ProductID = p.ProductID
        INNER JOIN SalesLT.ProductCategory AS pc
            ON p.ProductCategoryID = pc.ProductCategoryID
        WHERE soh.CustomerID = ?
        GROUP BY soh.OrderDate, pc.Name
        ORDER BY soh.OrderDate, pc.Name;
        """
        if len(customer) == 0:
            spend_df = load_data(SPEND_QUERY_ALL)
        else:
            customer_id = int(df.loc[customer, 'CustomerID'].values[0])
            spend_df = load_data(SPEND_QUERY_CUSTOMER, params=(customer_id,))
    
        st.write("Here's a summary of spend by product category over time:")
        st.bar_chart(spend_df.set_index('ProductCategory')['spend'], use_container_width=True)
    
        if len(customer) > 0:
            st.write(f"Displaying orders for Customer ID: {df.loc[customer, 'CustomerID'].values[0]}")
            customer_id = int(df.loc[customer, 'CustomerID'].values[0])
            SQL_QUERY = """
            SELECT *
            FROM SalesLT.SalesOrderHeader AS soh
            WHERE soh.CustomerID = ?;
            """
            st.dataframe(load_data(SQL_QUERY, params=(customer_id,)), hide_index=True, use_container_width=True)
            SQL_QUERY = """
            SELECT sod.*
            FROM SalesLT.SalesOrderHeader AS soh
            INNER JOIN SalesLT.SalesOrderDetail AS sod
                ON soh.SalesOrderID = sod.SalesOrderID
            WHERE soh.CustomerID = ?;
            """
            st.dataframe(load_data(SQL_QUERY, params=(customer_id,)), hide_index=True, use_container_width=True)
    
  4. Между импортом и def page_load() -> None:добавьте этот код.

    _connection = None
    
    def get_connection() -> Connection:
        global _connection
        if not _connection:
            load_dotenv()
            _connection = connect(getenv("SQL_CONNECTION_STRING"))
        return _connection
    
    @st.cache_data
    def load_data(SQL_QUERY, params=None) -> pd.DataFrame:
        data = pd.read_sql_query(SQL_QUERY, get_connection(), params=params)
        return data
    
  5. Найдите этот код.

    def main():
        print("Hello from rapid-prototyping-qs!")
    
  6. Замените его этим кодом.

    def main() -> None:
        page_load()
        if _connection:
            _connection.close()
    
  7. Сохраните и закройте main.py.

Сохранение строки подключения

  1. .gitignore Откройте файл и добавьте исключение для .env файлов. Ваш файл должен быть похож на следующий пример.

    # Python-generated files
    __pycache__/
    *.py[oc]
    build/
    dist/
    wheels/
    *.egg-info
    
    # Virtual environments
    .venv
    
    # Connection strings and secrets
    .env
    
  2. Сохраните и закройте .gitignore.

  3. В текущем каталоге создайте новый файл с именем .env.

  4. В файле .env добавьте запись для строки подключения с именем SQL_CONNECTION_STRING. Замените заполнители фактическими значениями.

    SQL_CONNECTION_STRING="Server=<server>;Database=<database>;Encrypt=yes;TrustServerCertificate=no;Authentication=ActiveDirectoryInteractive"
    

    Строка строка подключения зависит от типа SQL-базы данных, к которой вы подключаетесь. Для База данных SQL Azure или базы данных SQL в Fabric используйте строку подключения ODBC со вкладки строк подключения и настройте тип аутентификации под ваш сценарий. Для получения дополнительной информации о синтаксисе строка подключения см. раздел Connection strings for mssql-python.

    Подсказка

    На macOS, оба ActiveDirectoryInteractive и ActiveDirectoryDefault работают для проверки подлинности Microsoft Entra. ActiveDirectoryInteractive запрашивает вход при каждом запуске скрипта. Чтобы избежать повторяющихся запросов при входе, войдите один раз с помощью команды Azure CLIaz login и используйте ActiveDirectoryDefault. ActiveDirectoryDefault повторно использует кэшированные учетные данные.

Использование uv run для выполнения скрипта

  1. В окне терминала до или в новом окне терминала, открываемом в том же каталоге, выполните следующую команду.

    uv run streamlit run main.py
    

    Отчет откроется на новой вкладке в веб-браузере.

  2. Попробуйте свой отчет, чтобы узнать, как он работает. Если изменить что-либо, сохраните main.py и используйте параметр перезагрузки в правом верхнем углу окна браузера.

  3. Чтобы предоставить общий доступ к прототипу, скопируйте все файлы, кроме .venv папки на другой компьютер. Папка .venv повторно создается при первом запуске.