Copying Objects¶
PlexosDB allows you to create copies of existing objects along with their properties, memberships, and related property records.
Basic Object Copying¶
Copy an object and all its properties:
from plexosdb import PlexosDB
from plexosdb.enums import ClassEnum, CollectionEnum
# Initialize database
db = PlexosDB.from_xml("/path/to/model.xml")
# Assumes the model already contains a generator named "Generator1".
db.add_property(
ClassEnum.Generator,
object_name="Generator1",
name="Max Capacity",
value=100.0,
scenario="Base Case"
)
db.add_property(
ClassEnum.Generator,
object_name="Generator1",
name="Max Energy",
value=20.0,
scenario="Base Case"
)
# Copy a generator with all its properties
new_object_id = db.copy_object(
object_class=ClassEnum.Generator,
original_object_name="Generator1",
new_object_name="Generator1_Copy",
copy_properties=True # Default is True
)
print(f"Created new object with ID: {new_object_id}")
Copying Objects Without Properties¶
You can also copy the object and its memberships without copying properties:
# Add Generator object
db.add_object(ClassEnum.Generator, "Generator1")
# Add property
db.add_property(
ClassEnum.Generator,
object_name="Generator1",
name="Max Capacity",
value=20.0,
scenario="Base Case"
)
# Copy object structure only
new_object_id = db.copy_object(
object_class=ClassEnum.Generator,
original_object_name="Generator1",
new_object_name="Generator1_Skeleton",
copy_properties=False
)
Copying Memberships¶
When copying an object, PlexosDB also attempts to copy its memberships (except any that cannot be recreated due to model constraints):
# First create some objects with memberships
db.add_object(ClassEnum.Region, "Region1")
db.add_object(ClassEnum.Node, "Node1")
# Add membership
db.add_membership(
parent_class_enum=ClassEnum.Region,
child_class_enum=ClassEnum.Node,
parent_object_name="Region1",
child_object_name="Node1",
collection_enum=CollectionEnum.ReferenceNode
)
# Now copy the node with its memberships
new_object_id = db.copy_object(
object_class=ClassEnum.Node,
original_object_name="Node1",
new_object_name="Node1_Copy",
copy_properties=False
)
# Check the memberships of the new object
memberships = db.list_object_memberships(
ClassEnum.Node,
name="Node1_Copy"
)
print(f"New object has {len(memberships)} memberships")
Programmatic Membership Copying¶
You can also copy all non-system memberships programmatically:
db.add_object(ClassEnum.Node, "Node1")
db.add_object(ClassEnum.Generator, "Generator1")
db.add_object(ClassEnum.Generator, "Generator1_Copy")
db.add_membership(
parent_class_enum=ClassEnum.Generator,
child_class_enum=ClassEnum.Node,
parent_object_name="Generator1",
child_object_name="Node1",
collection_enum=CollectionEnum.Nodes
)
membership_mapping = db.copy_object_memberships(
object_class=ClassEnum.Generator,
original_name="Generator1",
new_name="Generator1_Copy"
)
print(f"Copied {len(membership_mapping)} memberships")
Practical Example: Duplicating a Set of Objects¶
This example shows how to duplicate a group of related objects:
# Create a function to copy memberships from an existing generator
def duplicate_generator_with_connections(db, original_name, new_name):
# Create the new generator (memberships are copied manually below)
db.add_object(ClassEnum.Generator, new_name)
# Find and copy all connections
memberships = db.list_object_memberships(
ClassEnum.Generator,
name=original_name,
exclude_system_membership=True
)
# Process each membership to maintain the network structure
for membership in memberships:
if membership["parent_name"] == original_name:
# Original generator was the parent, connect child to new generator
db.add_membership(
parent_class_enum=ClassEnum[membership["parent_class_name"]],
child_class_enum=ClassEnum[membership["child_class_name"]],
parent_object_name=new_name,
child_object_name=membership["child_name"],
collection_enum=CollectionEnum[membership["collection_name"]]
)
else:
# Original generator was the child, connect new generator to parent
db.add_membership(
parent_class_enum=ClassEnum[membership["parent_class_name"]],
child_class_enum=ClassEnum[membership["child_class_name"]],
parent_object_name=membership["parent_name"],
child_object_name=new_name,
collection_enum=CollectionEnum[membership["collection_name"]]
)
return new_name
# Existing generator to duplicate
db.add_object(ClassEnum.Generator, "Generator1")
# Use the function to duplicate a generator with all its connections
duplicate_generator_with_connections(db, "Generator1", "Generator1_Full_Copy")
Note
When copying objects with properties that reference other objects (like “Node” for a generator), you may need to update these properties manually if you want them to reference different objects.