Nova postagem

查找

Artigo
· Set. 29, 2025 3min de leitura

Importar datos CSV en InterSystems IRIS y preservar los IDs

¡Hola a todos!

Es muy fácil importar datos CSV en IRIS. Pero, ¿qué pasa si queremos preservar los IDs originales del CSV?

Recientemente me encontré con la situación en la que necesitaba importar dos CSVs en IRIS que estaban vinculados por una columna que hacía referencia a la columna de otro CSV: una situación típica de clave primaria y clave externa, donde csv1 contiene esta columna como clave primaria, y csv2 como clave externa con IDs relacionados con csv1.

La imagen fue generada por ChatGPT, así que no lo culpéis: hizo lo mejor que pudo al generar países como claves primarias con una relación countries.csv–cities.csv :)

Conozco al menos tres utilidades prácticas para importar CSV: csvgencsvgen-python, y bdb-sql-utils. Pero si importo ambos CSVs, por ejemplo mediante csvgen, habrá dos clases en IRIS con los datos importados, un ID interno generado y un IDKey. Y no es posible cambiar el IDKey a otro índice en la clase una vez que ya tiene datos. Así que resulta que no es tan obvio cómo importar un CSV y preservar una columna con datos de ID como IDKey en IRIS.

Por supuesto que es posible, y estoy seguro de que conocéis muchas maneras de hacerlo. De hecho, ahora es posible importar y preservar los IDs existentes en el CSV como claves ID tanto en csvgen como en csvgen-python. Para generar una clase en IRIS e importar datos desde un CSV dado con una clave primaria, proporcionad el nombre de la columna en el parámetro pkey (el último). De este modo, la utilidad añadirá un índice IDKey, PrimaryKey a la clase.
Por ejemplo, si importamos countries.csv y queremos que la columna Name sea un IDKey y clave primaria, llamad a csvgen de la siguiente manera:

//primary key name is the 11th parameter :)
zw ##class(community.csvgen).Generate("path/to/countries.csv,",","package.Countries",,,,,,,,"Name")

Lo que hace internamente puede describirse de la siguiente manera:

  • genera la clase con las propiedades como siempre,
  • borra todos los datos,
  • elimina el índice DDLBEIndex bitmap si existe (esto impide crear un IDKey alternativo al ya existente),
  • establece (temporalmente) la opción global del sistema DDLPKeyNotIDKey=0,
  • añade un índice Primary Key para la columna indicada con el nombre proporcionado.

Y como resultado, tendréis una clase recién generada con datos y la clave primaria IDKey para el nombre de columna dado.

Aquí está el código en csvgen.

Entonces, ¿cómo conectáis dos clases generadas? En mi caso necesitaba tener swizzling de instancias de class1 en class2.property. Así que simplemente cambié el tipo de dato en la clase generada a una clase con Primary Key–IdKey.

Aquí está la aplicación demo de ejemplo que analiza el consumo de patatas y la importación en distintos países (no me preguntéis por qué inventé este ejemplo; quizá tenía hambre). Los países son reales, pero el consumo fue generado por gpt, él/ella dijo que está cercano a la realidad, ya que resultó bastante difícil conseguir estos datos.

Aquí están countries.csv y potatos_sales.csv.

Así es como importo los datos y genero las clases:

    zpm "install csvgen"
    set file="/home/irisowner/dev/data/countries.csv"
    zw ##class(community.csvgen).Generate(file,",","esh.csvpkey.Countries",,,,,,,,"Name")
    set file="/home/irisowner/dev/data/potato_sales.csv"
    zw ##class(community.csvgen).Generate(file,",","esh.csvpkey.Potatos",,,,,1)

Genera una clase countries con PrimaryKey:

Class esh.csvpkey.Countries Extends %Persistent [ ClassType = persistent, DdlAllowed, Final, Owner = {irisowner}, ProcedureBlock, SqlRowIdPrivate, SqlTableName = Countries ]
{

Property Name As %Library.String(MAXLEN = 250) [ SqlColumnNumber = 2 ];
Property Code As %Library.String(MAXLEN = 250) [ SqlColumnNumber = 3 ];
...

Index COUNTRIESPKEY1 On Name [ IdKey, PrimaryKey, SqlName = COUNTRIES_PKEY1, Unique ];
...

}

Luego cambié la propiedad generada countries de %String a referencia a la clase countries:

Property Country As esh.csvpkey.Countries [ SqlColumnNumber = 2 ];

Y he creado una demo muy evidente de IRIS BI/DSW para ver cómo va el consumo de patatas en los distintos países a lo largo de los años:

Espero que os fuera interesante y os sirviera de ayuda :)

Discussão (0)1
Entre ou crie uma conta para continuar
Resumo
· Set. 29, 2025
Artigo
· Set. 28, 2025 3min de leitura

Everyone makes mistakes

I still remember the very first code I wrote in Object Script

Coming from Python, it felt so strange at first, but over time I started to see why the language was built the way it is.

If you’re just starting out, keep in mind that ObjectScript might feel a bit niche and mostly tied to IRIS products, but the way you work with it can really pay off - fast development, a powerful database, and a solid platform to learn on.

Sometimes it feels like you’ve stepped into a world that’s both familiar and different.

You’ll recognize bits of SQL, object-oriented concepts, but all mixed together in its own unique style. And like with any language, beginners tend to fall into a few common traps.

Scope matters

A lot of mistakes come from skipping the basics, things like how variables are scoped or how data persists aren’t just little details - they’re the foundation. I’ve seen new developers accidentally overwrite values because they didn’t realize local and global variables behave differently, slow down, take the time to really understand those fundamentals, and you’ll save yourself a lot of headaches later.

Functional or OOP?

Object Script is a unique blend, some people try to treat it like pure functional language, others like a standard object-oriented language - Neither works perfectly, the real strength is when you use both, every task and there is own solution, lean on SQL when it makes sense, wrote a fast-functional code, and switch to OO patterns when that’s the better fit.

Don’t overcomplicate things

Another trap I’ve noticed is when we writing way too much code for a simple problem, because Object Script feels different, people sometimes force patterns from other languages onto it, but most of the time, there’s already a simpler way built in - Before you write that big loop or extra class, ask yourself -  is there an easier way to do this here? Usually, the answer is yes.

Don’t ignore error handling

When you’re just trying to “get it working,” it’s easy to skip proper error handling, but when something breaks - and it will believe me - that’s when you feel the pain, learning how to catch, log, and handle errors early makes debugging so much easier and saves your teammates (and future self) a ton of frustration.

Globals stick around

globals are powerful, but they’re also persistent - that means your data hangs around until you clean it up, new devs or even mid often forget this, and end up with messy leftovers polluting their results, treat globals carefully and make sure you’re not leaving behind junk data.

Write code people can read

It’s one thing to get something working, it’s another to make sure someone else can understand it later, consistent naming, comments, and keeping things simple go a long way, you might think you’ll remember what your code does - but you won’t.

clean code is a kindness to yourself and anyone who has to work with it after you.

Enjoy the journey is really what matters

Discussão (0)2
Entre ou crie uma conta para continuar
Pergunta
· Set. 28, 2025

InitialExpression Not Working in %CSP.Page Subclass

Hello Community

The InitialExpression keyword values does not to set default values for properties in classes that extend %CSP.Page, unlike in other class types such as %Persistent or %RegisteredObject, where it works as expected during object instantiation (typically via %New()).

  1. Is %CSP.Page instantiated using %New() under the hood, or does it use a different initialization mechanism?
  2. Are there specific limitations or behaviors in CSP pages that prevent InitialExpression from working as expected?

Thank you!

5 Comments
Discussão (5)3
Entre ou crie uma conta para continuar
Anúncio
· Set. 26, 2025

[Video] August Developer Meetup Recording - Agentic Orchestration & Multi-LLM Systems

Hey Community,

The InterSystems team recently held another monthly Developer Meetup in the AWS Boston office location in the Seaport, breaking our all-time attendance record with over 80 attendees! This meetup was our second time being hosted by our friends at AWS, and the venue was packed with folks excited to learn from our awesome speakers.

 

The topic of the August meetup was Agentic Orchestration &  Multi-LLM Systems, and our speakers brought some amazing demos: First,  @Nicholai Mitchko demonstrated a financial document analysis using an implementation of a novel multi-LLM approach based on new research. Then, @Jayesh Gupta dove into a survey of approaches to orchestrating agentic systems.

If you weren't able to attend, we've once again recorded both talks from the meetup to make them available virtually. You can find the recorded sessions at the links below:

⏯️ Building Reliable Multi-LLM Systems for Financial Document Analysis

⏯️ Building Agentic Orchestration Systems (and other cool stuff)


 

Discussão (0)1
Entre ou crie uma conta para continuar