Skip to main content

Data Population Basics

Data Population Basics

To use the populate utility, do the following:

  1. Modify each persistent and each serial class that you want to populate with data. Specifically, add %PopulateOpens in a new tab to the end of the list of superclasses, so that the class inherits the interface methods. For example, if a class inherits directly from %PersistentOpens in a new tab, its new superclass list would be:

    Class MyApp.MyClass Extends (%Persistent,%Populate) {}

    Do not use %PopulateOpens in a new tab as a primary superclass; that is, do not list it as the first class in the superclass list.

  2. In those classes, optionally specify the POPSPEC and POPORDER parameters of each property, to control how the populate utility generates data for those properties, if you want to generate custom data rather than the default data, which is described in the next section.

  3. Recompile the classes.

  4. To generate the data, call the Populate() method of each persistent class. By default, this method generates 10 records for the class (including any serial objects that it references):

     Do ##class(MyApp.MyClass).Populate()

    If you prefer, you can specify the number of objects to create:

     Do ##class(MyApp.MyClass).Populate(num)

    where num is the number of objects that you want.

    Do this in the same order in which you would add records manually for the classes. That is, if Class A has a property that refers to Class B, use the following table to determine which class to populate first:

    If the property in Class A has this form... And Class B inherits from... Populate this class first...
    Any of these forms:
    • Property PropertyName as ClassB;

    • Property PropertyName as List of ClassB;

    • Property PropertyName as Array of ClassB;

    %SerialObjectOpens in a new tab ClassA (this populates ClassB automatically)
    Any of these forms:
    • Property PropertyName as ClassB;

    • Property PropertyName as List of ClassB;

    • Property PropertyName as Array of ClassB;

    %PersistentOpens in a new tab ClassB
    Any of these forms:
    • Relationship PropertyName as ClassB [ Cardinality = one ...];

    • Relationship PropertyName as ClassB [ Cardinality = parent ...];

    %SerialObjectOpens in a new tab or %PersistentOpens in a new tab ClassB
    Any of these forms:
    • Relationship PropertyName as ClassB [ Cardinality = many...];

    • Relationship PropertyName as ClassB [ Cardinality = child ...];

    %SerialObjectOpens in a new tab or %PersistentOpens in a new tab ClassA

Later, to remove the generated data, use either the %DeleteExtent() method (safe) or the %KillExtent() method (fast) of the persistent interface. For more information, see Deleting Saved Objects.

Tip:

In practice, it is often necessary to populate classes repeatedly, as you make changes to your code. Thus it is useful to write a method or a routine to populate classes in the correct order, as well as to remove the generated data.

Populate() Details

Formally, the Populate() class method has the following signature:

classmethod Populate(count As %Integer = 10, 
                     verbose As %Integer = 0, 
                     DeferIndices As %Integer = 1, 
                     ByRef objects As %Integer = 0, 
                     tune As %Integer = 1,
                     deterministic As %Integer = 0) as %Integer

Where:

  • count is the desired number of objects to create.

  • verbose specifies whether the method should print progress messages to the current device.

  • DeferIndices specifies whether to sort indexes after generating the data (true) or while generating the data.

  • objects, which is passed by reference, is an array that contains the generated objects.

  • tune specifies whether to run $SYSTEM.SQL.TuneTable() after generating the data. If this is 0, the method does not run $SYSTEM.SQL.TuneTable(). If this is 1 (the default), the method runs $SYSTEM.SQL.TuneTable() for this table. If this is any value higher than 1, the method runs $SYSTEM.SQL.TuneTable() for this table and for any tables projected by persistent superclasses of this class.

  • deterministic specifies whether to generate the same data each time you call the method. By default, the method generates different data each time you call it.

Populate() returns the number of objects actually populated:

 Set objs = ##class(MyApp.MyClass).Populate(100)
 // objs is set to the number of objects created.
 // objs will be less than or equal to 100

In cases with defined constraints, such as a minimum or maximum length, some of the generated data may not pass validation, so that individual objects will not be saved. In these situations, Populate() may create fewer than the specified number of objects.

If errors prevent objects from being saved, and this occurs 1000 times sequentially with no successful saves, Populate() quits.

FeedbackOpens in a new tab