查找

InterSystems 官方
· 一月 21

Alerte : données non valides introduites dans la base de données et les fichiers journaux avec des opérations $LIST spécifiques

InterSystems a corrigé un défaut qui provoque l'introduction d'enregistrements de base de données et de journaux non valides lors de l'utilisation d'une syntaxe $LIST spécifique. La probabilité de rencontrer ce défaut est très faible, mais les impacts opérationnels peuvent être importants.

Produits concernés

  • Plateforme de données InterSystems IRIS® : versions 2023.3, 2024.1.0, 2024.1.1, 2024.1.2, 2024.2, 2024.3
  • InterSystems IRIS® for Health : versions 2023.3, 2024.1.0, 2024.1.1, 2024.1.2, 2024.2, 2024.3
  • HealthShare® Health Connect : versions 2023.3.0, 2024.1, 2024.1.1, 2024.1.2, 2024.2, 2024.3
  • HealthShare® Unified Care Record and Suite : version 2024.2
  • Toutes les offres basées sur les produits ci-dessus

Le problème concerne uniquement les installations Unicode.

Le problème survient lors de l'ajout d'un nouvel élément à une liste dans un nœud global à l'aide de la syntaxe suivante :

SET $LIST(<global reference>, *+1) = value

Lorsque la liste résultant de cet appel dépasse la longueur de chaîne maximale, le comportement correct consiste à renvoyer une erreur <MAXSTRING>. C'est ce qui se produisait avant la version 2023.3 d'InterSystems IRIS, InterSystems IRIS for Health et Health Connect. Dans la version 2023.3 et les versions ultérieures, la valeur non valide est enregistrée dans la base de données au lieu de générer une erreur <MAXSTRING>.

Toute tentative ultérieure de référencement du nœud global génère une erreur <MAXSTRING>.

La mise à jour globale génère également un enregistrement de journal (en supposant que les mises à jour de ce nœud global soient normalement journalisées). Toute opération qui tente d'appliquer l'enregistrement de journal résultant, y compris la récupération au démarrage, la restauration du journal et les opérations de mise en miroir, échouera avec une erreur <MAXSTRING> et arrêtera le traitement ultérieur du fichier journal.

Si vous constatez les conséquences de ce défaut, contactez le Worldwide Response Center (WRC) pour obtenir de l'aide.

La correction de ce défaut est identifiée comme DP-437169. Elle sera incluse dans toutes les versions futures à partir d'InterSystems IRIS, InterSystems IRIS for Health et Health Connect 2024.1.3 et 2025.1.0. Elle est également disponible via une distribution ad hoc. La correction sera incluse dans HealthShare Unified Care Record version 2025.1 et dans la suite de produits dès leur sortie, mais ne sera pas incluse dans les versions de maintenance des versions précédentes. Si vous avez des questions concernant cette alerte, veuillez contacter le Worldwide Response Center.

讨论 (0)0
登录或注册以继续
Job
· 一月 21

Vacante: Ingeniero/a de IRIS

Traduzco esta oferta del a comunidad Inglesa de @Parwez Wahid

Están buscando un perfil con:

  • Experiencia imprescindible en la plataforma IRIS for Health (versión 2021 y superiores)
  • Programación y desarrollo de componentes en ObjectScript (5+ años)
  • Experiencia en HL7 (ADT’s) y FHIR (3+ años)
  • Experiencia en IRIS IKO’s, GKE, K8’s y tecnología en la nube (2+ años)
  • Experiencia en IRIS Ensemble Cache, SDA’s


Contacto:

Saumaya Dubey
512-523-6988
saumya@steneral.com

1 Comment
讨论 (1)1
登录或注册以继续
文章
· 一月 21 阅读大约需 1 分钟

¿Qué versión tiene mi imagen?

Si queréis averiguar qué versión exacta tiene vuestra imagen (y dado que con el último esquema de etiquetado de imágenes no podéis confiar únicamente en la etiqueta de la imagen; y suponiendo que no queréis ejecutarla solo para averiguarlo), podéis ejecutar este comando de Docker:

docker inspect irepo.intersystems.com/intersystems/irishealth:latest-preview --format '{{ index .Config.Labels "com.intersystems.platform-version" }}'

(Por supuesto, adaptad la imagen a la que os estáis refiriendo)

Y la salida será, por ejemplo:

2025.1.0L.152.0

Lo encontré útil, por ejemplo, para comparar qué versión estoy ejecutando frente a otras versiones disponibles. Esto sería importante con lanzamientos de mantenimiento menores de versiones de EM y, como en mi ejemplo anterior, con lanzamientos de Developer Preview.

Tened en cuenta que este comando docker inspect es un enfoque similar al que @Dmitry Maslennikov compartió aquí para obtener los puertos predeterminados que usa el contenedor, y está en línea con la documentación que hace referencia al descubrimiento de los valores predeterminados de la imagen (como en el caso de Dmitry).

讨论 (0)1
登录或注册以继续
问题
· 一月 21

¿Índice en campo TimeStamp, o mejor en Date?

Tengo una tabla con un campo TimeStamp. Necesito crearle un índice para mejorar la ejecución de consultas. Pero estoy dándole vueltas a cuál podría ser la mejor opción.

Había pensado en separar el campo TimeStamp en dos campos: Date y Hour, siendo este último un campo Integer que solo almacene la hora, ya que las búsquedas, en realidad, se hacen o solo por fecha, o por fecha y hora, sin contar minutos ni segundos. A estos dos nuevos campos le puedo poner un índice de tipo bitmap, al TimeStamp no. Creo que esto acelera las búsquedas, al menos en el análisis del plan de consulta es lo que aparece.

¿Cuál sería la mejor opción?

  • Crear un índice normal en el campo TimeStamp
  • Crear dos nuevos campos, Date y Hour con índices de tipo bitmap (o normales quizá)
  • Otro?

He hecho varias pruebas y parece que la opción de separarlo en dos campos es la más rápida, pero quería saber vuestra opinión.

Gracias!!

5 Comments
讨论 (5)2
登录或注册以继续
文章
· 一月 20 阅读大约需 10 分钟

Getting to know Python Streamlit Web Framework - Part2

Hi, Community!

In the previous article, we introduced the Streamlit web framework, a powerful tool that enables data scientists and machine learning engineers to build interactive web applications with minimal effort. First, we explored how to install Streamlit and run a basic Streamlit app. Then, we incorporated some of Streamlit's basic commands, e.g., adding titles, headers, markdown, and displaying such multimedia as images, audio, and videos.

Later, we covered Streamlit widgets, which allow users to interact with the app through buttons, sliders, checkboxes, and more. Additionally, we examined how to display progress bars and status messages and organize the app with sidebars and containers. We also highlighted data visualization, using charts and Matplotlib figures to present data interactively.

In this article, we will cover the following topics:

  1. Connecting to IRIS and loading data
  2. Secrets Management
  3. Caching
  4. Session State
  5. Theming
  6. Pages

Let's dive right in!

1. Connecting to IRIS and loading data

In this section, we will establish a connection with IRIS, fetch data from the "%SYS.ProcessQuery" table, and display it in our Streamlit application. To establish the connection, we will use SQLAlchemy, the Python SQL toolkit that serves as a bridge between Python code and relational databases. For more details, please refer to this article

The script below utilizes SQLAlchemy to connect to an InterSystems IRIS database, retrieve information about running processes from the %SYS.ProcessQuery table, and display the data as an interactive table with the help of the st.dataframe element in Streamlit.

import streamlit as st
from sqlalchemy import create_engine,text
import pandas as pd

#Init connection parameters
username="_SYSTEM"
password="***" #Replace with password
host="localhost"
port=1972
namespace="%SYS"
#Construct connection string
CONNECTION_STRING = f"iris://{username}:{password}@{host}:{port}/{namespace}"
#Init connection
engine = create_engine(CONNECTION_STRING)

#Set page layout
st.set_page_config(layout="wide")

st.subheader("IRIS Running Processes")

#Establish connection
with engine.connect() as conn:
    with conn.begin(): 
        sql = text("""
                SELECT * FROM %SYS.ProcessQuery ORDER BY NameSpace desc        
                """)
        results = []   
        try:
            #Fetch all records
            results = conn.execute(sql).fetchall()
        except Exception as e:
            print(e)
#Load records to dataframe
df = pd.DataFrame(results)

# Remove comma formatting for integer columns
df = df.applymap(lambda x: f"{x}" if isinstance(x, int) else x)
# Replace NaN with an empty string
df = df.fillna("")
#Set ID column
df = df.set_index(df.columns[0])  
#Display Data
st.dataframe(df, use_container_width=True, height=700) 


2. Secret Management

Streamlit provides a convenient mechanism for Secret management. For now, let's explore only how connection parameters work with secrets. In our local project directory, we can save our secrets in a .streamlit/secrets.toml file. For instance, if we have an app file irisCon.py, our project directory may look like the following:

your-LOCAL-repository/
├── .streamlit/
│   └── secrets.toml # Make sure to gitignore this!
└── irisCon.py

For the example mentioned above, our secrets.toml file might resemble the next lines:

[irisLocal]
username="_SYSTEM"
password="***" #Replace password
host="localhost"
port=1972
namespace="%SYS"

Below you can find the updated code:

import streamlit as st
from sqlalchemy import create_engine,text
import pandas as pd

#Init connection parameters
username=st.secrets["irisLocal"]["username"]
password=st.secrets["irisLocal"]["password"]
host=st.secrets["irisLocal"]["host"]
port=st.secrets["irisLocal"]["port"]
namespace=st.secrets["irisLocal"]["namespace"]

#Construct connection string
CONNECTION_STRING = f"iris://{username}:{password}@{host}:{port}/{namespace}"
#Init connection
engine = create_engine(CONNECTION_STRING)

#Set page layout
st.set_page_config(layout="wide")

st.subheader("IRIS Running Processes")

#Establish connection
with engine.connect() as conn:
    with conn.begin(): 
        sql = text("""
                SELECT * FROM %SYS.ProcessQuery ORDER BY NameSpace desc        
                """)
        results = []   
        try:
            #Fetch all records
            results = conn.execute(sql).fetchall()
        except Exception as e:
            print(e)
#Load records to dataframe
df = pd.DataFrame(results)

# Remove comma formatting for integer columns
df = df.applymap(lambda x: f"{x}" if isinstance(x, int) else x)
# Replace NaN with an empty string
df = df.fillna("")
#Set ID column
df = df.set_index(df.columns[0])  
#Display Data
st.dataframe(df, use_container_width=True, height=700) 

3. Caching

Caching is an essential feature for optimizing the performance of our Streamlit app, particularly when handling large datasets, performing time-consuming calculations, or fetching data from external sources. By caching the results of expensive function calls, we can prevent redundant execution and speed up our application responsiveness.

The concept of caching is simple: instead of rerunning the same function with identical inputs multiple times, Streamlit stores the result of the first execution and returns the cached result for subsequent calls with the same inputs. It eliminates unnecessary recomputations.

In Streamlit, we can cache functions by applying a decorator. There are two main caching decorators to choose from:

  1. st.cache_data: This caching method is the preferred one for functions that return data. It is ideal for functions that generate serializable objects (e.g., strings, integers, floats, DataFrames, lists, or dictionaries). The cache stores a fresh copy of the data each time the function is run, ensuring it remains immutable which helps to avoid such issues as race conditions. For most use cases, this is the recommended method.
  2. st.cache_resource: This decorator is designed to cache such global resources as machine learning models or database connections. You should use it when your function returns non-serializable objects you do not wish to reload on every app rerun. With st.cache_resource, the object itself is cached and shared across reruns and sessions without duplication. Please note that mutations to cached objects will persist across all runs and sessions.

Check out below how you can apply caching to a function:

@st.cache_data
def long_running_function(param1, param2):
    return

In this example, the function long_running_function is decorated with @st.cache_data. Streamlit takes notes of the following:

  • The function name (long_running_function).
  • The values of the parameters (param1, param2).
  • The code inside the function.

Before executing the function, Streamlit scans the cache for a matching result based on the function name and input parameters. If it finds a cached result, it returns it instead of rerunning the function. If no cache is discovered, Streamlit runs the function, stores the result, and proceeds with the script. During development, the cache automatically updates when the function code changes, ensuring that you always use the latest version.

4. Session State

Session State provides a flexible way to store and persist information across multiple interactions with your Streamlit app. The st.session_state object helps us save data that remains intact between reruns of our app, making it ideal for managing user-specific settings or variables during a session. We can store values using a key-value structure. For instance, we can access or keep data utilizing st.session_state["my_key"] or st.session_state.my_key.

While widgets in Streamlit automatically manage their state (e.g., storing user inputs), there are times when you might need to manage more complex states manually. This is when the Session State comes into play.

What is a Session?

In Streamlit, a session refers to the unique instance in which a user interacts with the app. If you open the app in different browser tabs or windows, each one will create a separate session with its own session state. The session remains active as long as the user interacts with the app. However, if the user refreshes the page or restarts the app, the session state is reset, and they begin with a fresh session.

Practical Example of Session State Usage

Below there is a simple example where we keep track of the number of times a button has been clicked. Each time the button is pressed, the page reruns, and the counter value gets updated:

import streamlit as st

if "counter" not in st.session_state:
    st.session_state.counter = 0
st.session_state.counter += 1
st.header(f"This page has been run {st.session_state.counter} times.")
st.button("Run it again")
  • First run: The first time the app runs for each user, the Session State is empty. Therefore, a key-value pair is created ("counter":0). As the script continues, the counter is immediately incremented ("counter":1) and the result is displayed: "This page has run 1 time." When the page has fully rendered, the script finishes, and the Streamlit server starts waiting for the user to do something.
  • Second run: Since "counter" is already a key in Session State, it does not get reinitialized. As the script resumes, the counter gets incremented ("counter":2), and the result is shown: "This page has run 2 times."

5. Theming

Streamlit supports two themes out of the box - Light and Dark. First, it checks if the user viewing an app has any mode preferences set by their operating system and browser. If there is one, then that preference will be used. Otherwise, the Light theme is applied by default.

You can also change the active theme from "⋮" → "Settings".


Do you wish to personalize your app’s theme? Simply navigate to the "Settings" menu and click "Edit active theme" to access the theme editor. This tool allows you to explore various color schemes and see the real-time alterations applied to your app.

6-Pages

As apps are growing large, organizing them into multiple pages becomes crucial. It simplifies the management and maintenance for developers and navigation for users. Streamlit provides a smooth way to create multipage apps.

This feature is designed to make building a multipage app just as easy as creating a single-page app! Just add additional pages to an existing app as shown below:

  1. In the folder containing your main script, create a new pages folder. Let’s say your main script would be named main_page.py.
  2. Add new .py files in the pages folder to add more pages to your app.
  3. Run streamlit run main_page.py as usual.
your-LOCAL-repository/
├── pages/
│   └── page_2.py
│   └── page_3.py
└── irisCon.py

That’s it! The main_page.py script will now correspond to the main page of your app. You will also see the other scripts from the pages folder in the sidebar page selector. The pages will be listed according to filename (without file extensions and disregarding underscores). For instance:

#main_page.py
import streamlit as st 
st.markdown("# Main page 🎈") 
st.sidebar.markdown("# Main page 🎈")
#page_2.py
import streamlit as st 
st.markdown("# Page 2 ❄️") 
st.sidebar.markdown("# Page 2 ❄️")
#page_3.py
import streamlit as st
st.markdown("# Page 3 🎉") 
st.sidebar.markdown("# Page 3 🎉")

Now run streamlit run main_page.py and enjoy the view of your shiny new multipage app!

 

 

 

 

 

 

 

 

 

 

 

 

 

 


Summary

 

 

 

 

 

 

 

In this article, we have explored several key features of Streamlit that enhance the functionality of our applications. We started by learning how to connect to an InterSystems IRIS database and retrieve data, using SQLAlchemy for seamless integration. Then we covered the importance of managing sensitive information securely with Streamlit’s secrets management system. We also introduced caching to optimize app performance, ensuring faster load times by avoiding redundant computations. Additionally, we delved into Session State, allowing us to maintain user-specific data across app reruns. Along the way, we highlighted theming and customization, demonstrating how to tailor the application appearance for a personalized experience. Ultimately, we discussed the organization of larger apps with multiple pages, making the management easier for developers and users. With all the above-mentioned techniques, you are finally equipped to build more interactive, efficient, and user-friendly Streamlit applications.

 

 

 

 

 

 

 

Thanks!

1 Comment
讨论 (1)2
登录或注册以继续