In Python I iterate database rows with 'for row in cursor'. How do I process collections of records in EK9?

← Getting Started · Ref: Q1012

EK9 provides two approaches: for-in loops and stream pipelines.

Python:

  for row in cursor:
      if row['active']:
          print(f"{row['name']}: {row['score']}")

EK9 LOOP APPROACH:

  for entry in records
    if entry.active?
      stdout.println(`${entry.personName}: ${$entry.score}`)

EK9 STREAM APPROACH:

  cat records | filter by isActive > stdout

The stream approach is preferred when you are filtering, transforming, or collecting. The loop approach is fine for simple iteration with side effects.

For transforming results into a new collection:
Python: names = [row['name'] for row in cursor if row['active']]
EK9: names <- cat records | filter by isActive | map with extractName | collect as List of String

Example

defines module qa.gettingstarted.frompythoniteration

  defines record

    UserRecord
      personName as String: String()
      score as Integer: 0
      active as Boolean: false

      UserRecord()
        ->
          personName as String
          score as Integer
          active as Boolean
        this.personName :=: personName
        this.score :=: score
        this.active :=: active

      default operator

  defines function

    isActive() as pure
      -> entry as UserRecord
      <- rtn as Boolean: entry.active

    extractName() as pure
      -> entry as UserRecord
      <- rtn as String: entry.personName

  defines program

    IterationDemo()
      stdout <- Stdout()

      records <- [
        UserRecord("Alice", 95, true),
        UserRecord("Bob", 42, false),
        UserRecord("Charlie", 88, true),
        UserRecord("Diana", 73, false),
        UserRecord("Eve", 91, true)
      ]

      // Stream approach: filter active, print
      stdout.println("Active users:")
      cat records | filter by isActive > stdout

      // Stream approach: filter, transform, collect
      activeNames <- cat records
        | filter by isActive
        | map with extractName
        | collect as List of String
      stdout.println(`Active names: ${activeNames}`)

Common mistakes

E01081 — EK9 has no list-comprehension syntax — use a stream pipeline: cat source | filter by fn | map with fn | collect as Type. See ek9 -h E01081 for details.

Incorrect:

      activeNames <- [entry.personName for entry in records if entry.active]

Correct:

      activeNames <- cat records
        | filter by isActive
        | map with extractName
        | collect as List of String
Other ways to ask this
  • How do I iterate over results and transform them in EK9?
  • What is the EK9 equivalent of Python's for loop with transformation?
  • How do I process a list of records in EK9?

Coming from another language?

Python developers: for-in loops work similarly. For filter/map/collect patterns, use stream pipelines instead of list comprehensions.

Keywords: stream, iteration, for, cursor, transform, migration, python