Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 20 additions & 8 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,22 @@
# AGENTS.md

- Assume concurrent human/agent work; never revert or overwrite changes you did not author.
- This repo processes model data into SQLite; watch query/transform cost, memory churn, and fixture representativeness.
- Prefer minimal, behavior-proven changes; add regression coverage for bug fixes and use existing fixtures under `tests/fixtures` or `tests/data` when practical.
- No breadcrumbs after deleting or moving code; remove the old code/comment instead of leaving relocation notes.
- Use `uv sync --all-groups` for setup. For changed areas, run the narrow relevant check first; before broad handoff use `uv run prek run --show-diff-on-failure --color=always --all-files --hook-stage pre-push` when feasible.
- Type-check package changes with `uv run ty check --output-format github ./src/plexosdb`.
- Test package changes with `uv run pytest --cov --cov-report=xml`; benchmark-sensitive changes may need `uv run pytest benchmarks/ -k "not xlarge_300k" --benchmark-only --benchmark-json=benchmark-results.json --no-cov`.
- Build docs for user/operator-facing documentation changes with `uv run sphinx-build docs/source/ docs/_build/`.
- Assume concurrent human/agent work; never revert or overwrite changes you did
not author.
- This repo processes model data into SQLite; watch query/transform cost, memory
churn, and fixture representativeness.
- Prefer minimal, behavior-proven changes; add regression coverage for bug fixes
and use existing fixtures under `tests/fixtures` or `tests/data` when
practical.
- No breadcrumbs after deleting or moving code; remove the old code/comment
instead of leaving relocation notes.
- Use `uv sync --all-groups` for setup. For changed areas, run the narrow
relevant check first; before broad handoff use
`uv run prek run --show-diff-on-failure --color=always --all-files --hook-stage pre-push`
when feasible.
- Type-check package changes with
`uv run ty check --output-format github ./src/plexosdb`.
- Test package changes with `uv run pytest --cov --cov-report=xml`;
benchmark-sensitive changes may need
`uv run pytest benchmarks/ -k "not xlarge_300k" --benchmark-only --benchmark-json=benchmark-results.json --no-cov`.
- Build docs for user/operator-facing documentation changes with
`uv run sphinx-build docs/source/ docs/_build/`.
107 changes: 75 additions & 32 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,70 +4,113 @@ All notable changes to this project will be documented in this file.

## [1.4.1](https://github.com/NatLabRockies/plexosdb/compare/v1.4.0...v1.4.1) (2026-05-22)


### 🐛 Bug Fixes

* copy_object date range metadata copying ([#143](https://github.com/NatLabRockies/plexosdb/issues/143)) ([b60e5ad](https://github.com/NatLabRockies/plexosdb/commit/b60e5ad21032f05702ed74bb345f3f4579e2379d))
- copy_object date range metadata copying
([#143](https://github.com/NatLabRockies/plexosdb/issues/143))
([b60e5ad](https://github.com/NatLabRockies/plexosdb/commit/b60e5ad21032f05702ed74bb345f3f4579e2379d))

## [1.4.0](https://github.com/NatLabRockies/plexosdb/compare/v1.3.4...v1.4.0) (2026-05-21)


### 🚀 Features

* add new Purchaser enum for handling new type of loads ([#127](https://github.com/NatLabRockies/plexosdb/issues/127)) ([c5d9a38](https://github.com/NatLabRockies/plexosdb/commit/c5d9a38e29ba929869c0194da4fddca3860bcc3c))
* address mixed issues ([#128](https://github.com/NatLabRockies/plexosdb/issues/128)) ([eabaa5b](https://github.com/NatLabRockies/plexosdb/commit/eabaa5bdd80e3898a5ddb37aa082b4736f4579e9))

- add new Purchaser enum for handling new type of loads
([#127](https://github.com/NatLabRockies/plexosdb/issues/127))
([c5d9a38](https://github.com/NatLabRockies/plexosdb/commit/c5d9a38e29ba929869c0194da4fddca3860bcc3c))
- address mixed issues
([#128](https://github.com/NatLabRockies/plexosdb/issues/128))
([eabaa5b](https://github.com/NatLabRockies/plexosdb/commit/eabaa5bdd80e3898a5ddb37aa082b4736f4579e9))

### 🐛 Bug Fixes

* add safe parsing for long int values ([#140](https://github.com/NatLabRockies/plexosdb/issues/140)) ([c565313](https://github.com/NatLabRockies/plexosdb/commit/c565313d5b37839def642261ab05dd493ab1e879))
* resolve bug on add properties from records related methods ([#129](https://github.com/NatLabRockies/plexosdb/issues/129)) ([b3f4dbb](https://github.com/NatLabRockies/plexosdb/commit/b3f4dbb5d85cb2077e0402b499fa929a67221df7))

- add safe parsing for long int values
([#140](https://github.com/NatLabRockies/plexosdb/issues/140))
([c565313](https://github.com/NatLabRockies/plexosdb/commit/c565313d5b37839def642261ab05dd493ab1e879))
- resolve bug on add properties from records related methods
([#129](https://github.com/NatLabRockies/plexosdb/issues/129))
([b3f4dbb](https://github.com/NatLabRockies/plexosdb/commit/b3f4dbb5d85cb2077e0402b499fa929a67221df7))

### 📦 Build

* **deps-dev:** bump ipython from 9.8.0 to 9.13.0 ([#137](https://github.com/NatLabRockies/plexosdb/issues/137)) ([98c66d4](https://github.com/NatLabRockies/plexosdb/commit/98c66d4046183ae059e6bc4354913809f711e74a))
* **deps-dev:** bump sphinxcontrib-mermaid from 1.0.0 to 2.0.2 ([#136](https://github.com/NatLabRockies/plexosdb/issues/136)) ([8c26ac3](https://github.com/NatLabRockies/plexosdb/commit/8c26ac3ee0ffe32060d90b74d68745c3434117dd))
* **deps:** bump actions/upload-artifact from 7.0.0 to 7.0.1 ([#121](https://github.com/NatLabRockies/plexosdb/issues/121)) ([85194fe](https://github.com/NatLabRockies/plexosdb/commit/85194fec3d3c14f924ec0f33126271ceb0ec8524))
* **deps:** bump astral-sh/setup-uv from 7.6.0 to 8.1.0 ([#122](https://github.com/NatLabRockies/plexosdb/issues/122)) ([e189e14](https://github.com/NatLabRockies/plexosdb/commit/e189e146477ee75f38e70c473d0b612979ed787f))
* **deps:** bump benchmark-action/github-action-benchmark from 1.21.0 to 1.22.0 ([#120](https://github.com/NatLabRockies/plexosdb/issues/120)) ([4ac3c99](https://github.com/NatLabRockies/plexosdb/commit/4ac3c991fd18d703caceb68c38dc7556477d2385))
* **deps:** bump codecov/codecov-action from 5.5.3 to 6.0.0 ([#118](https://github.com/NatLabRockies/plexosdb/issues/118)) ([fc5c2e8](https://github.com/NatLabRockies/plexosdb/commit/fc5c2e8834f1932f960db3003a70d0a0dee9df87))
* **deps:** bump googleapis/release-please-action from 4.4.0 to 4.4.1 ([#123](https://github.com/NatLabRockies/plexosdb/issues/123)) ([8959d18](https://github.com/NatLabRockies/plexosdb/commit/8959d183c9872c450906af288148ba033d45b77f))
- **deps-dev:** bump ipython from 9.8.0 to 9.13.0
([#137](https://github.com/NatLabRockies/plexosdb/issues/137))
([98c66d4](https://github.com/NatLabRockies/plexosdb/commit/98c66d4046183ae059e6bc4354913809f711e74a))
- **deps-dev:** bump sphinxcontrib-mermaid from 1.0.0 to 2.0.2
([#136](https://github.com/NatLabRockies/plexosdb/issues/136))
([8c26ac3](https://github.com/NatLabRockies/plexosdb/commit/8c26ac3ee0ffe32060d90b74d68745c3434117dd))
- **deps:** bump actions/upload-artifact from 7.0.0 to 7.0.1
([#121](https://github.com/NatLabRockies/plexosdb/issues/121))
([85194fe](https://github.com/NatLabRockies/plexosdb/commit/85194fec3d3c14f924ec0f33126271ceb0ec8524))
- **deps:** bump astral-sh/setup-uv from 7.6.0 to 8.1.0
([#122](https://github.com/NatLabRockies/plexosdb/issues/122))
([e189e14](https://github.com/NatLabRockies/plexosdb/commit/e189e146477ee75f38e70c473d0b612979ed787f))
- **deps:** bump benchmark-action/github-action-benchmark from 1.21.0 to 1.22.0
([#120](https://github.com/NatLabRockies/plexosdb/issues/120))
([4ac3c99](https://github.com/NatLabRockies/plexosdb/commit/4ac3c991fd18d703caceb68c38dc7556477d2385))
- **deps:** bump codecov/codecov-action from 5.5.3 to 6.0.0
([#118](https://github.com/NatLabRockies/plexosdb/issues/118))
([fc5c2e8](https://github.com/NatLabRockies/plexosdb/commit/fc5c2e8834f1932f960db3003a70d0a0dee9df87))
- **deps:** bump googleapis/release-please-action from 4.4.0 to 4.4.1
([#123](https://github.com/NatLabRockies/plexosdb/issues/123))
([8959d18](https://github.com/NatLabRockies/plexosdb/commit/8959d183c9872c450906af288148ba033d45b77f))

## [1.3.4](https://github.com/NatLabRockies/plexosdb/compare/v1.3.3...v1.3.4) (2026-03-27)


### 🧩 CI

* use release/v1 tag for pypa/gh-action-pypi-publish ([#107](https://github.com/NatLabRockies/plexosdb/issues/107)) ([c4e58b8](https://github.com/NatLabRockies/plexosdb/commit/c4e58b8dc062f3302216b3caa7c9c6c1cc423c86))

- use release/v1 tag for pypa/gh-action-pypi-publish
([#107](https://github.com/NatLabRockies/plexosdb/issues/107))
([c4e58b8](https://github.com/NatLabRockies/plexosdb/commit/c4e58b8dc062f3302216b3caa7c9c6c1cc423c86))

### 📦 Build

* **deps:** bump actions/cache from 5.0.3 to 5.0.4 ([#115](https://github.com/NatLabRockies/plexosdb/issues/115)) ([1ff162a](https://github.com/NatLabRockies/plexosdb/commit/1ff162afe66dfe3bcad7d0dbb0a534b4a9d3374a))
* **deps:** bump astral-sh/setup-uv from 7.5.0 to 7.6.0 ([#117](https://github.com/NatLabRockies/plexosdb/issues/117)) ([13fb3cf](https://github.com/NatLabRockies/plexosdb/commit/13fb3cfb4c7a2affd7df504a2e152c9a2b0c1295))
* **deps:** bump astral-sh/setup-uv from b75dde52aef63a238519e7aecbbe79a4a52e4315 to e06108dd0aef18192324c70427afc47652e63a82 ([#114](https://github.com/NatLabRockies/plexosdb/issues/114)) ([96f3975](https://github.com/NatLabRockies/plexosdb/commit/96f397540b06e68e45075a5d700d2b0a91ebe112))
* **deps:** bump codecov/codecov-action from 5.5.2 to 5.5.3 ([#116](https://github.com/NatLabRockies/plexosdb/issues/116)) ([c86c8e2](https://github.com/NatLabRockies/plexosdb/commit/c86c8e254a85909043c8a7b25a10ff7d169d1e02))
* **deps:** bump googleapis/release-please-action from c3fc4de07084f75a2b61a5b933069bda6edf3d5c to 16a9c90856f42705d54a6fda1823352bdc62cf38 ([#112](https://github.com/NatLabRockies/plexosdb/issues/112)) ([4150d56](https://github.com/NatLabRockies/plexosdb/commit/4150d56065f41cf916912daf9cda39281cf4e3df))
* **deps:** bump peaceiris/actions-gh-pages from e9c66a37f080288a11235e32cbe2dc5fb3a679cc to 4f9cc6602d3f66b9c108549d475ec49e8ef4d45e ([#113](https://github.com/NatLabRockies/plexosdb/issues/113)) ([c697f1d](https://github.com/NatLabRockies/plexosdb/commit/c697f1d7642dac4c16cd5ea9e11e327d684ff548))
- **deps:** bump actions/cache from 5.0.3 to 5.0.4
([#115](https://github.com/NatLabRockies/plexosdb/issues/115))
([1ff162a](https://github.com/NatLabRockies/plexosdb/commit/1ff162afe66dfe3bcad7d0dbb0a534b4a9d3374a))
- **deps:** bump astral-sh/setup-uv from 7.5.0 to 7.6.0
([#117](https://github.com/NatLabRockies/plexosdb/issues/117))
([13fb3cf](https://github.com/NatLabRockies/plexosdb/commit/13fb3cfb4c7a2affd7df504a2e152c9a2b0c1295))
- **deps:** bump astral-sh/setup-uv from
b75dde52aef63a238519e7aecbbe79a4a52e4315 to
e06108dd0aef18192324c70427afc47652e63a82
([#114](https://github.com/NatLabRockies/plexosdb/issues/114))
([96f3975](https://github.com/NatLabRockies/plexosdb/commit/96f397540b06e68e45075a5d700d2b0a91ebe112))
- **deps:** bump codecov/codecov-action from 5.5.2 to 5.5.3
([#116](https://github.com/NatLabRockies/plexosdb/issues/116))
([c86c8e2](https://github.com/NatLabRockies/plexosdb/commit/c86c8e254a85909043c8a7b25a10ff7d169d1e02))
- **deps:** bump googleapis/release-please-action from
c3fc4de07084f75a2b61a5b933069bda6edf3d5c to
16a9c90856f42705d54a6fda1823352bdc62cf38
([#112](https://github.com/NatLabRockies/plexosdb/issues/112))
([4150d56](https://github.com/NatLabRockies/plexosdb/commit/4150d56065f41cf916912daf9cda39281cf4e3df))
- **deps:** bump peaceiris/actions-gh-pages from
e9c66a37f080288a11235e32cbe2dc5fb3a679cc to
4f9cc6602d3f66b9c108549d475ec49e8ef4d45e
([#113](https://github.com/NatLabRockies/plexosdb/issues/113))
([c697f1d](https://github.com/NatLabRockies/plexosdb/commit/c697f1d7642dac4c16cd5ea9e11e327d684ff548))

## [1.3.3](https://github.com/NatLabRockies/plexosdb/compare/v1.3.2...v1.3.3) (2026-03-16)


### 🐛 Bug Fixes

* **ci:** harden all workflows per zizmor audit ([#105](https://github.com/NatLabRockies/plexosdb/issues/105)) ([67ca845](https://github.com/NatLabRockies/plexosdb/commit/67ca84584d1e66410dc66b014a9b710a24b00b95))

- **ci:** harden all workflows per zizmor audit
([#105](https://github.com/NatLabRockies/plexosdb/issues/105))
([67ca845](https://github.com/NatLabRockies/plexosdb/commit/67ca84584d1e66410dc66b014a9b710a24b00b95))

### ⚡ Performance

* Improving performance of adding memberships from records ([#104](https://github.com/NatLabRockies/plexosdb/issues/104)) ([1ea4a39](https://github.com/NatLabRockies/plexosdb/commit/1ea4a39612a1bef1a0f290eaeb40441874a2b8f0))

- Improving performance of adding memberships from records
([#104](https://github.com/NatLabRockies/plexosdb/issues/104))
([1ea4a39](https://github.com/NatLabRockies/plexosdb/commit/1ea4a39612a1bef1a0f290eaeb40441874a2b8f0))

### 📦 Build

* **deps:** bump actions/download-artifact from 7 to 8 ([#101](https://github.com/NatLabRockies/plexosdb/issues/101)) ([0e572a0](https://github.com/NatLabRockies/plexosdb/commit/0e572a07a930f6e25f196e98fc879f65f7dd9daa))
* **deps:** bump actions/upload-artifact from 6 to 7 ([#102](https://github.com/NatLabRockies/plexosdb/issues/102)) ([22b8374](https://github.com/NatLabRockies/plexosdb/commit/22b8374aa7ed9d29eb36258a6a5ad16feb2e21c5))
- **deps:** bump actions/download-artifact from 7 to 8
([#101](https://github.com/NatLabRockies/plexosdb/issues/101))
([0e572a0](https://github.com/NatLabRockies/plexosdb/commit/0e572a07a930f6e25f196e98fc879f65f7dd9daa))
- **deps:** bump actions/upload-artifact from 6 to 7
([#102](https://github.com/NatLabRockies/plexosdb/issues/102))
([22b8374](https://github.com/NatLabRockies/plexosdb/commit/22b8374aa7ed9d29eb36258a6a5ad16feb2e21c5))

## [1.3.2](https://github.com/NatLabRockies/plexosdb/compare/v1.3.1...v1.3.2) (2026-02-12)

Expand Down
160 changes: 133 additions & 27 deletions docs/source/howtos/add_attributes.md
Original file line number Diff line number Diff line change
@@ -1,22 +1,37 @@
# Adding Attributes to the objects
# Working with Attributes

Objects in PlexosDB can have attributes that are saved on the `t_attribute_data`
table.
Objects in PlexosDB can have attributes stored in the `t_attribute_data` table.

Attributes are different from properties in the following ways:

- Attribute definitions are valid for a class and are stored in `t_attribute`.
- Attribute values are assigned directly to individual objects in
`t_attribute_data`.

```{note}
See the [API Reference](api/index.md) for class-specific attribute
tables that list available attributes, default values, validation rules and
descriptions.
```

## Listing available attributes per `ClassEnum`

To see the list of available attributes per `ClassEnum` use:
We can use `list_attributes()` to see which attributes are valid for a specific
class. This returns definitions, not values assigned to a particular object.

```python
from plexosdb import PlexosDB, ClassEnum
db = PlexosDB.from_xml("/path/to/your/xml")
from plexosdb import ClassEnum, PlexosDB
db = PlexosDB.from_xml("/path/to/your/model.xml")

attributes = db.list_attributes(ClassEnum.Generator)
print(attributes)
```

## Adding an attribute to an existing object

We can use `add_attribute()` to assign one attribute value. The object must
already exist and the attribute name must be valid for its class.

```python
from plexosdb import PlexosDB
from plexosdb.enums import ClassEnum, CollectionEnum
Expand All @@ -30,38 +45,129 @@ if not db.check_object_exists(ClassEnum.Generator, "Generator1"):
db.add_object(ClassEnum.Generator, "Generator1")

# Add a property to the generator
attribute_name = "Latitude"
db.add_attribute(
ClassEnum.Generator,
"Generator1",
attribute_name="Latitude",
attribute_value=100.0,
)
```

## Extracting a single attribute from an object

We can use `get_attribute()` when we know the attribute name and need its
assigned value.

```python
step_count = db.get_attribute(
ClassEnum.Generator,
object_name="Generator1",
attribute_name=attribute_name,
attribute_value=100.0
attribute_name="Latitude",
)
print(step_count)
```

## Extracting an attribute from an object
## Extracting all assigned attributes from an object

We can use `get_attributes()` to retrieve all values assigned to an object.

```python
from plexosdb import PlexosDB
from plexosdb.enums import ClassEnum, CollectionEnum
attributes = db.get_attributes(
"2020",
object_class=ClassEnum.Horizon,
)

# Initialize database
db = PlexosDB()
db.create_schema()
for attribute in attributes:
print(attribute["attribute"], attribute["value"])
```

# Create a generator object if it doesn't exist
if not db.check_object_exists(ClassEnum.Generator, "Generator1"):
db.add_object(ClassEnum.Generator, "Generator1")
The result contains dictionaries with the following keys:

# Add a property to the generator
attribute_name = "Latitude"
db.add_attribute(
ClassEnum.Generator,
object_name="Generator1",
attribute_name=attribute_name,
attribute_value=19.8
```text
name
attribute
value
state
```

We can also filter to one attribute or a group of attributes.

```python
step_type = db.get_attributes(
"2020",
object_class=ClassEnum.Horizon,
attribute_names="Step Type",
)

step_attributes = db.get_attributes(
"2020",
object_class=ClassEnum.Horizon,
attribute_names=["Chrono Step Count", "Step Type"],
)
```

If the object exists but has no assigned values matching the request,
`get_attributes()` returns an empty list.

## Checking and deleting assigned attributes

We can use `check_attribute_exists()` to determine whether an object has an
assigned value for a particular attribute.

```python
has_step_count = db.check_attribute_exists(
"Chrono Step Count",
object_name="2020",
object_class=ClassEnum.Horizon,
)

print(has_step_count)
```

We can use `delete_attribute()` to remove an assigned value.

```python
db.delete_attribute(
"Chrono Step Count",
object_name="2020",
object_class=ClassEnum.Horizon,
)
```

## Adding attributes in bulk

We can use `add_attributes_from_records()` when assigning values to many
objects. The method accepts either explicit records or a wide format.

For explicit records we can use one row per object and attribute:

```python
db.add_attributes_from_records(
[
{"name": "2020", "attribute": "Chrono Step Count", "value": 366},
{"name": "2020", "attribute": "Step Type", "value": 4},
{"name": "2021", "attribute": "Chrono Step Count", "value": 365},
],
object_class=ClassEnum.Horizon,
)
```

db.get_attribute(ClassEnum.Generator, object_name="Generator1",
attribute_name=attribute_name)
For wide records we can use one column per attribute:

```python
db.add_attributes_from_records(
[
{
"name": "2020",
"Chrono Step Count": 366,
"Step Type": 4,
},
{
"name": "2021",
"Chrono Step Count": 365,
"Step Type": 4,
},
],
object_class=ClassEnum.Horizon,
)
```
21 changes: 21 additions & 0 deletions docs/source/howtos/bulk_operations.md
Original file line number Diff line number Diff line change
Expand Up @@ -227,3 +227,24 @@ your model:

This approach can dramatically improve performance when creating large, complex
models.

## Bulk Inserting Attributes

For efficiently adding multiple attribute values, use
`add_attributes_from_records`.

### Basic Usage (Wide Format)

```python
from plexosdb.enums import ClassEnum

records = [
{"name": "Horizon1", "Step Type": 4.0, "Chrono Step Count": 366.0},
{"name": "Horizon2", "Step Type": 4.0, "Chrono Step Count": 365.0},
]

db.add_attributes_from_records(
records,
object_class=ClassEnum.Horizon,
)
```
Loading