Changelog¶
All notable changes to TypeBridge will be documented in this file.
[Unreleased]¶
[1.4.4] - 2026-04-09¶
New Features¶
Cross-type attribute lookup (PR #117)¶
Entity.has / Relation.has / <Concrete>.has โ find all instances that own a
given attribute, optionally filtered by value or expression.
Python ORM โ type_bridge.crud.has_lookup¶
- Cross-type form โ
Entity.has(db, Name)returns mixed concrete subtypes across all entities owningName. - Concrete-class narrowing โ
HLPerson.has(db, Name)narrows to that type and its TypeDB subtypes viaisapolymorphism. Abstract base subclasses get subtype matching for free. - Role-player hydration โ relation results always include hydrated role players. Entity lookups remain single-query; relations are re-fetched per result through
concrete_class.manager(connection).get(_iid=iid). Attribute.get_owners()โ static discovery of attribute owners without a database connection, backed by a reverse_attribute_ownersindex inModelRegistry.
[1.4.3] - 2026-04-05¶
Bug Fixes¶
Rust Server โ type-bridge-server¶
- fix:
extract_crud_info()now reports the write-target type for Match + Insert/Put queries (#121)
Rust Core โ type-bridge-core-lib¶
- refactor: use idiomatic match guards in validation.rs
[1.4.2] - 2026-03-04¶
Rust Server โ type-bridge-server¶
CrudInfoonRequestContextโ operation, type_name, type_kind, attribute_names, iidCrudInterceptortrait withon_crud_request/on_crud_responseandshould_interceptCrudInterceptorAdapterbridgesCrudInterceptorinto the existingInterceptorchain
[1.4.1] - 2026-03-03¶
New Features¶
Lifecycle Hook System (PR #118, closes #116)¶
Three-layer hook system for reacting to CRUD lifecycle events (audit logging, validation, cache invalidation, async notifications).
Python ORM โ type_bridge.crud.hooks¶
CrudEventenum โPRE_INSERT,POST_INSERT,PRE_UPDATE,POST_UPDATE,PRE_DELETE,POST_DELETE,PRE_PUT,POST_PUTLifecycleHookprotocol โ implement only the methods you need (pre_insert,post_delete, etc.)HookCancelledexception โ raise in a pre-hook to abort the operation- Per-manager registration โ
manager.add_hook(hook)/manager.remove_hook(hook), chainable should_run(event, sender)filtering by event type or model class- Pre-hooks run in registration order; post-hooks run in reverse order (middleware unwinding)
- Zero overhead when no hooks are registered
Rust ORM โ type-bridge-orm¶
LifecycleHooktrait withHookContext,PreHookResult(Continue/Reject), andHookRunner- Integrated into
EntityManagerandRelationManagerviaadd_hook() - Same semantics as the Python layer (registration-order pre-hooks, reverse-order post-hooks)
Put (Upsert) Clause โ type-bridge-core-lib¶
- Added
Clause::Put(Vec<Statement>)variant for idempotent insert (upsert) operations - Parser:
parse_put_clausewith keyword lookahead in bothparse_patternsandparse_statements - Compiler: Generates
put\n<statements>;TypeQL output - Validation: Reuses Insert validation rules (
Clause::Insert | Clause::Put) - Full roundtrip support (parse โ AST โ compile โ parse)
Refactoring¶
Server API Simplification โ type-bridge-server¶
- Removed standalone CRUD module (
/entities/*,/relations/*endpoints,CrudQueryBuilder, raw query support) โ superseded by the interceptor-based design - Removed
crud_builderbenchmark andcriteriondev-dependency - Server now has 4 endpoints:
POST /query,POST /query/validate,GET /health,GET /schema
[1.4.0] - 2026-02-20¶
Highlights¶
- 5 new Rust crates:
core-lib,orm,orm-derive,server, andpython(PyO3 bindings) - Up to 40x faster validation and 2.5x faster query compilation via the Rust backend
- Async Rust ORM with derive macros, chainable queries, and batch operations
- Query-intercepting proxy server with REST endpoints
- MkDocs Material documentation site
New Features¶
Rust Core โ type-bridge-core-lib (PRs #95, #101-#108)¶
- TypeQL schema parser with inheritance resolution and PyO3 bindings
- TypeQL query parser with bidirectional AST roundtrip
- Schema-aware query validation with statement and pattern validators
- Rust-backed value coercion and
format_value - Custom validation rules with portable JSON DSL
- Wired Rust core into Python compiler and validation pipeline
Async Rust ORM โ type-bridge-orm (PR #114)¶
- Async ORM with entity CRUD and mock-testable session layer
- Derive macros โ
#[derive(TypeBridgeEntity)],#[derive(TypeBridgeRelation)],#[derive(TypeBridgeAttribute)] - Chainable query builders with expression filtering and aggregation
- Schema management โ registration, generation, diff, and sync
- Abstract types with inheritance and code generation
- Batch operations โ
insert_many,delete_many,update_many FieldRef<A>for type-safe query field referencesinclude_schema!proc-macro for compile-time TQL codegen- Schema introspection from live TypeDB database
- Group-by queries with
GroupByResult - Role player field access for relation query filtering
- Expression helpers โ
in_range(),startswith(),endswith() - Connection pooling with
Database::into_shared() - Serde support on all ORM model types
- Structured tracing spans on all public methods
Query Intercept Proxy โ type-bridge-server (PR #109)¶
- REST CRUD endpoints with schema-aware query building
CrudQueryBuilderPyO3 class for TypeQL generation from Python- Extensible library/framework โ pluggable
QueryExecutor,Interceptor,SchemaSource - 207 tests with 100% MC/DC coverage
Performance: Python vs Rust¶
Validation¶
| Operation | Python | Rust | Speedup |
|---|---|---|---|
| Single type name | 1.89 us | 354.75 ns | 5.3x |
| Long name (100+ chars) | 24.90 us | 620.52 ns | 40.1x |
| Batch 1,000 names | 5.32 ms | 266.80 us | 19.9x |
| Batch 5,000 names | 28.02 ms | 1.33 ms | 21.1x |
Query Compilation (via serde bridge)¶
| Operation | Python | Rust | Speedup |
|---|---|---|---|
| Standalone update | 93.28 us | 37.82 us | 2.5x |
| Large batch (200 clauses) | 2.26 ms | 1.07 ms | 2.1x |
| Heavy insert (100x6) | 1.71 ms | 896.19 us | 1.9x |
Documentation & CI¶
- MkDocs + Material documentation site with auto-generated API reference (PR #98)
- Rust crate CI with multi-platform wheel builds โ Linux (x86_64, aarch64), macOS (x86_64, aarch64), Windows (x86_64) (PR #95)
- Comprehensive benchmark suite with TOML storage, comparison reports, and markdown generation (PR #103)
- Codecov integration for Rust coverage tracking (PR #109)
Bug Fixes¶
- Resolve Rust 1.93.0 clippy lint errors
- Pin Python 3.13 for Rust CI jobs and fix coverage script
- Add version specifiers to inter-crate path dependencies for crates.io publishing
- Make release workflow idempotent (skip already-published packages)
[1.3.0] - 2026-02-09¶
New Features¶
API DTO Generator (PRs #96, #97, #99, #100)¶
- Pydantic DTO generation from TypeQL schemas โ Generate typed Create/Out/Patch DTOs directly from parsed schemas
- Composite DTOs โ
CompositeEntityConfigfor flat/merged DTOs across entity types with name clash validation - Per-variant field requiredness overrides โ
FieldOverrideandEntityFieldOverrideto control field requiredness per DTO variant (Create, Out, Patch) skip_variantsโ Skip generating specific variant classes while keeping the type Literal enumextra_fields_outโ Per-variant override for extra fields on Out DTOsstrict_out_modelsโ Flag for required fields in Out DTOs- Reusable Jinja macros โ Refactored templates into
_dto_macros.jinja - CLI support โ
python -m type_bridge.generatornow supports DTO generation
Date Arithmetic and Query-Level Arithmetic Expressions¶
- Date arithmetic โ
__add__,__radd__,__sub__onDatefor Duration arithmetic, matching DateTime/DateTimeTZ - ArithmeticExpr โ New expression class with helpers (
add,sub,mul,div,mod,pow_) for TypeQL infix operators - ArithmeticValue AST node and compiler support
Improvements¶
- TypeDB 3.8.0 stable โ Bumped from 3.8.0-rc0 to 3.8.0 release
- TypeDB driver 3.8.0 โ Upgraded
typedb-driverdependency to 3.8.0 - Expression module cleanup โ Improved handling across boolean, comparison, and string expression modules
- Field module cleanup โ Enhanced field handling in base and role modules
Housekeeping¶
- Applied ruff formatting to all test files
- Added
.coverageto.gitignore(was accidentally tracked)
[1.2.7] - 2026-02-03¶
New Features¶
TypeDB 3.8.0 Support (PR #93)¶
- Full compatibility with TypeDB 3.8.0
- Updated driver integration
Performance Improvements¶
Batch Operations Optimization¶
- Batch delete operations with disjunctive IID matching
- Batch entity inserts/puts into single query
- Optimized IID retrieval with single-query insert+fetch
Bug Fixes¶
- HydrationError handling - Raise HydrationError instead of silently swallowing exceptions
- Variable collision prevention - Use double underscore separator to prevent variable collisions
- TypeDB 3.x relation syntax - Use correct relation insert syntax with
linkskeyword - Multi-variable let fix - Remove incorrect parentheses in multi-variable let assignment
- Polymorphic attributes - Restore polymorphic attribute fetching with nested wildcard
Refactoring¶
- Consolidate duplicated code and fix Python 3.13 warnings
- Unify entity identification logic across managers
- Extract shared attribute-to-AST logic into TypeDBType
- Remove
.caccessor for direct field access
Code Quality¶
- Remove all
type: ignorecomments for full type safety
Testing¶
- Add recursive relation tests
- Add validation performance benchmarks
[1.2.6] - 2026-02-01¶
New Features¶
Polymorphic Role Player Type Resolution (PR #92)¶
- Role players now resolve to their concrete Python types
- When querying relations with abstract role types, role players are resolved to concrete types (e.g.,
Personinstead ofProfile) - Uses TypeQL
label()function to fetch type labels and resolve to correct Python class - Location:
type_bridge/crud/relation/manager.py
Relations as Role Players¶
- Fixed hydration for relations serving as role players
- Relations can now properly participate as role players in other relations
- Comprehensive test suites added for this pattern
- Location:
type_bridge/crud/relation/manager.py
Improvements¶
Modular Helper Methods (PR #92)¶
- Extracted reusable helper methods for DRY refactoring
_resolve_entity_class_from_label()- Resolves concrete types using TypeQLlabel()function_hydrate_entity_from_data()- Helper for role player instantiation- Eliminates duplicate code in
get()andget_by_iid()methods
Generator Enhancements (PR #92)¶
- Improved code generation for relations
- Role cardinality annotations now properly rendered
- Docstrings and type annotations rendering improvements
- Location:
type_bridge/generator/
Bug Fixes¶
Polymorphic Role Validation (PR #92)¶
- Fixed polymorphic role validation and role player IIDs
- Correct handling of abstract types in role player resolution
- Fixed role player IID extraction in polymorphic queries
Test Fixes (PR #92)¶
- Fixed
manager.count()โmanager.filter().count()in tests - Renamed attribute types to avoid naming collisions
Testing¶
- 19 new integration tests (
tests/integration/queries/test_social_network_queries.py) - Deep inheritance (3-level: Entity โ Profile โ Person/Organization)
- Self-referential symmetric relations (Friendship)
- Geographic hierarchy chains (Person โ City โ Country)
- Polymorphic role players with concrete type verification
- Multi-value attributes with
@card(0..*) - Chained relations and complex filter combinations
Key Files Modified¶
type_bridge/crud/relation/manager.py- Polymorphic role player resolutiontype_bridge/generator/render/- Role cardinality and annotations renderingtests/integration/queries/test_social_network_queries.py- New comprehensive tests
[1.2.5] - 2026-01-31¶
New Features¶
IID-preferring Role Player Matching (PR #91)¶
- RelationManager now prefers IID for role player matching
- Uses IID for precise matching when available
- Falls back to key attribute matching when IID not set
- Raises clear
ValueErrorwhen neither IID nor key attributes available - Location:
type_bridge/crud/relation/manager.py
Affected Methods: insert(), put(), update(), delete() and *_many variants
Documentation¶
- Updated role player matching docs in
docs/SKILL.mdanddocs/api/crud.md
[1.2.4] - 2026-01-30¶
New Features¶
TypeDB 3.8.0 Built-in Functions (PR #88)¶
- Added support for TypeDB 3.8.0 built-in functions
- Identity functions:
iid(),label() - Math functions:
abs_(),ceil(),floor(),round_() - Collection functions:
len_(),max_(),min_() - Location:
type_bridge/expressions/builtins.py
Usage Example:
from type_bridge.expressions import iid, label, abs_, ceil, floor
# Get entity IID
query = Person.manager(db).filter(iid() == "0x1a2b3c").execute()
# Use math functions
query = Person.manager(db).filter(abs_(Age.value) > 18).execute()
Unicode XID Identifier Validation (PR #88)¶
- Added Unicode identifier validation for TypeDB 3.8.0 compatibility
- Validates identifiers follow Unicode XID_Start/XID_Continue rules
- Ensures TypeQL identifiers are compatible with TypeDB 3.8.0
- Clear error messages for invalid identifiers
- Location:
type_bridge/validation.py
Bug Fixes¶
Value Extraction Fix (PR #88)¶
- Fixed value extraction for
_Valueconcepts - Changed from
.as_value()to.get()for proper value extraction - Fixes issues with function return values and aggregations
- Location:
type_bridge/session.py
Driver Initialization Warning Fix (PR #88)¶
- Fixed "Failed to initialize logging" warning
- Suppresses fd 2 (stderr) during TypeDB driver initialization
- Eliminates spurious warning messages on startup
- Location:
type_bridge/typedb_driver.py
Documentation¶
- Added AI Assistant Skill Documentation (
docs/SKILL.md) - Guidelines for using TypeBridge with AI code assistants
Testing¶
- 32 new unit tests for builtin expressions
- 7 new integration tests for
iid()andlabel()functions - All existing tests pass with TypeDB 3.8.0-rc0
- Fixed hardcoded port 1729 in tests to use TEST_DB_ADDRESS
CI/CD¶
- Updated CI to TypeDB 3.8.0-rc0
- All tests now run against TypeDB 3.8.0-rc0
Key Files Modified¶
type_bridge/expressions/builtins.py- New built-in function expressionstype_bridge/session.py- Value extraction fixtype_bridge/typedb_driver.py- Driver initialization fixtype_bridge/validation.py- Unicode identifier validationdocs/SKILL.md- New AI assistant documentation
[1.2.3] - 2025-12-28¶
New Features¶
Enhanced FunctionQuery System (PR #84)¶
- Complete TypeQL query generation for function calls
- FunctionQuery generates full
match letqueries with variable binding - Support for scalar returns, stream returns, and composite tuples
- Query methods:
to_call(),to_match_let(),to_fetch(),to_query() - Pagination support with limit/offset/sort
- Location:
type_bridge/expressions/functions.py
Usage Example:
from myschema.functions import count_artifacts, get_neighbor_ids
# Simple count
fn = count_artifacts()
query = fn.to_query()
# โ match let $integer = count-artifacts(); fetch { "integer": $integer };
# Stream with pagination
fn = get_neighbor_ids(target_id="abc-123")
query = fn.to_query(limit=10, offset=5)
Driver Injection Support (PR #86)¶
- Share TypeDB driver instances across Database objects
- Optional
driverparameter inDatabase.__init__() - Ownership tracking with
_owns_driverflag for lifecycle control - Enables connection pooling and framework integration
- Location:
type_bridge/session.py
Benefits: - Resource efficiency (share one TCP connection) - Application-level connection pooling strategies - Centralized driver lifecycle management - Backwards compatible (default behavior unchanged)
Usage Example:
driver = TypeDB.driver("localhost:1729", Credentials("admin", "password"))
db1 = Database(database="project_a", driver=driver) # Shares driver
db2 = Database(database="project_b", driver=driver) # Shares driver
db1.close() # Just clears reference
db2.close() # Just clears reference
driver.close() # Actually closes connection
@independent Annotation Support (PR #83)¶
- Standalone attributes without entity/relation owners
- Add
independent = TrueClassVar to attribute classes - Generates
@independentannotation in TypeQL schema - Enables standalone attribute insertion and queries
- Location:
type_bridge/attribute/base.py
Usage Example:
class Language(String):
"""Can exist without an owner."""
independent = True
# Generated TypeQL: attribute Language @independent, value string;
@range Validation and Schema Generation (PR #82)¶
- Runtime validation with database enforcement
IntegerandDoublevalidaterange_constraintClassVar at initialization- Schema generation includes
@range(min..max)annotations - Also generates
@regexand@valuesannotations from ClassVars - Two-layer validation: Python-side (fail-fast) + TypeDB-side (enforcement)
- Location:
type_bridge/attribute/integer.py,type_bridge/attribute/double.py
Usage Example:
from typing import ClassVar
class Age(Integer):
range_constraint: ClassVar[tuple[str | None, str | None]] = ("0", "150")
Age(200) # Raises: ValueError: Age value 200 is above maximum 150
# Generated schema: attribute Age, value integer @range(0..150);
Batch IID Filtering (PR #81)¶
- Django-style
iid__inlookup for efficient batch queries - Filter entities/relations by multiple IIDs in single query
- Role player filtering:
employee__iid__in=[...] - Uses flat BooleanExpr to avoid stack overflow with many IIDs
- Location:
type_bridge/expressions/iid.py,type_bridge/crud/entity/manager.py
Usage Example:
# Fetch multiple entities by IID
persons = Person.manager(db).filter(iid__in=["0x1a2b3c", "0x4d5e6f"]).execute()
# Filter relations by role player IIDs
employments = Employment.manager(db).filter(employee__iid__in=["0x1a2b3c"]).execute()
Performance: O(1) query vs O(N) get_by_iid() calls.
TypeQL Annotation Validation (PR #86)¶
- Comprehensive validation for schema annotations
@card: Validates min โค max, non-negative values, detects comma syntax@regex: Validates patterns compile as valid regex@values: Validates at least one value, detects duplicates@range: Validates proper..syntax, rejects comma/single-value- Clear, actionable error messages
- Location:
type_bridge/generator/parser.py
Bug Fixes¶
Code Generator Fixes (PR #86)¶
- Fixed relation inheritance to include keys, uniques, and cardinalities
- Child relations now inherit
@key,@unique, and@cardfrom parent - Ensures complete type definitions in generated code
-
Location:
type_bridge/generator/render/relations.py -
Fixed optional relation attributes in generated models
- Correct type hints with
| Nonefor optional fields - Proper default values (e.g.,
timestamp: Timestamp | None = None) - Respects cardinality:
@card(1)= required, no annotation = optional -
Location:
type_bridge/generator/render/relations.py -
Fixed Python literal rendering for @range annotations
- Range values output as numeric literals:
(1, None)not("1", null) - Fixed type hint from
str | Nonetoint | float | None - Location:
type_bridge/generator/render/attributes.py
Query Generation Fixes (PR #84)¶
- Fixed composite variable lists in FunctionQuery
- Removed incorrect parentheses around variable lists
- Correct:
match let $a, $b in func() - Incorrect (previous):
match let ($a, $b) in func() - Location:
type_bridge/expressions/functions.py
Type Checking Fixes¶
- Proper type annotations for ty type checker
- Use
type[Attribute]instead of generic type - Use
type[Entity] | type[Relation]for model params - Core library passes ty with zero warnings
-
Location:
type_bridge/crud/relation/lookup.py,type_bridge/schema/introspection.py -
Added None checks for optional attributes
assert position is not Noneguards before accessing.value- Fixes pyright errors in tests
- Location:
tests/integration/crud/test_iid_feature.py
Development & Tooling¶
Project Restructuring¶
- Moved Python package to repository root
- Transitioned from monorepo (
packages/python/) to root-level package - TypeScript split into separate type-bridge-ts repository
- Simplified CI/CD configuration
Pre-commit Hooks¶
- Comprehensive code quality automation
- ruff linting and formatting
- pyright type checking
- ty type checker for enhanced type safety
- Location:
.pre-commit-config.yaml
Type Checker Configuration¶
- Configured ty rules for metaclass compatibility
- Overrides for tests/examples to handle metaclass-generated code
- Rules: unknown-argument, unresolved-attribute, call-non-callable
- Location:
pyproject.toml[tool.ty.overrides]
Documentation¶
- FunctionQuery documentation and integration tests
- Comprehensive examples of query generation patterns
-
All function patterns tested (scalar, stream, composite)
-
Database driver injection guide
- Connection pooling examples
-
Framework integration patterns
-
Generator relation cardinality documentation
- Clarified
@cardbehavior on relation attributes - Required vs optional attribute patterns
Testing¶
- 1096 unit tests passing (100% pass rate)
- All integration tests passing
- 0 errors with pyright and ty type checkers
Key Files Modified¶
type_bridge/expressions/functions.py- Enhanced FunctionQuerytype_bridge/session.py- Driver injection supporttype_bridge/generator/parser.py- Annotation validationtype_bridge/generator/render/relations.py- Inheritance and optional attributestype_bridge/generator/render/attributes.py- Python literal renderingtype_bridge/crud/relation/lookup.py- Type annotationstype_bridge/schema/introspection.py- Type annotationstype_bridge/attribute/base.py- @independent supporttype_bridge/attribute/integer.py- @range validationtype_bridge/attribute/double.py- @range validation.pre-commit-config.yaml- Pre-commit hooks configurationpyproject.toml- ty type checker configuration
[1.2.2] - 2025-12-25¶
Bug Fixes¶
RelationManager IID Correlation Fix (Issue #78)¶
- Fixed incorrect IID assignment in RelationManager.all()
- Problem: All relations were getting the same IID values for their role players instead of unique IIDs for each relation
- Root cause:
_populate_iidsmethod didn't properly correlate query results to the correct relation instances - Solution: Capture key attribute values as variables in the query and build a lookup map for correlating results back to the correct relations
- Impact: Critical for code relying on role player
_iidvalues for deduplication or correlation - Example: Multiple friendships now correctly show unique IIDs for each person instead of all showing the same IIDs
- Location:
type_bridge/session.py,type_bridge/crud/relation/manager.py
Testing¶
- Added 133 lines of regression tests for Issue #78
- Verifies multiple relations each get their own unique IIDs
Key Files Modified¶
type_bridge/session.py- Added value extraction for attribute concepts in_extract_concept_rowtype_bridge/crud/relation/manager.py- Fixed IID correlation logic (198 additions, 134 deletions)tests/integration/crud/test_iid_feature.py- Added regression tests for Issue #78
[1.2.1] - 2025-12-25¶
Bug Fixes¶
Stack Overflow Fix for __in Lookup (Issue #76)¶
- Fixed TypeDB stack overflow when using
__inlookup with many values (75+) - Root cause: Deeply nested binary OR expressions
((((a or b) or c) or d)...)caused TypeDB query planner to stack overflow - Solution: Use flat BooleanExpr structure for OR operations
- Example:
manager.filter(name__in=["Alice", "Bob", ...150 names])now works reliably - Location:
type_bridge/crud/entity/manager.py,type_bridge/crud/relation/lookup.py,type_bridge/expressions/boolean.py - Added automatic flattening of BooleanExpr operations
BooleanExpr.and_()andBooleanExpr.or_()now automatically flatten operands of the same operation type- Prevents deeply nested expression trees
- Improves query compilation performance
Testing¶
- Added 249 new tests for BooleanExpr flattening and __in lookup edge cases
- All tests passing
Key Files Modified¶
type_bridge/crud/entity/manager.py- Flat OR structure for __in lookupstype_bridge/crud/relation/lookup.py- Flat OR structure for relation lookupstype_bridge/expressions/boolean.py- Automatic flattening in and_() and or_()tests/unit/crud/test_lookup_parser.py- Entity lookup tests (37 tests)tests/unit/crud/test_role_lookup_parser.py- Relation lookup tests (31 tests)tests/unit/expressions/test_boolean_expr.py- BooleanExpr flattening tests (181 tests)
[1.2.0] - 2025-12-22¶
New Features¶
TypeDB 3.0 Structs Support (PR #71)¶
- Parse and generate Python code for TypeDB struct types
- Structs are value types composed of named fields
- Full code generator support for struct definitions
- Location:
type_bridge/generator/
Additional Annotations Support (PR #71)¶
@rangeannotation rendering in code generator- Support for
@range(min..max)constraints on attributes - Renders as validation metadata in generated code
Role Player IIDs (PR #70)¶
- Populate IIDs on role player entities when fetching relations
- Role players now have their
_iidfield populated automatically - Enables direct IID-based lookups on role players
Generator CLI Enhancement (PR #70)¶
- New
--schema-pathCLI option for code generator - Specify custom path for schema file in generated output
Batch Delete Error Handling¶
strictparameter fordelete_many- Optional error handling for batch deletes- When
strict=True, raises error if any entity not found - When
strict=False(default), silently skips missing entities
Performance Improvements¶
Batch Query Optimizations (PR #75)¶
- 50-100x improvement for bulk operations
- Batch
update_withoperations to reduce round-trips - Batch
_populate_iidsfor efficient IID resolution - Significant performance gains for large datasets
N+1 Query Fix (PR #73)¶
- Fix N+1 query problem in entity IID/type resolution
- Previously: 1 query per entity for IID resolution
- Now: Single batched query for all entities
- Major performance improvement for
all()andfilter().execute()
Batched CRUD Operations¶
- Batched
update_manyanddelete_manyoperations - Efficient batch processing instead of per-entity queries
- Reduced database round-trips
Bug Fixes¶
- None check in
delete_many- Add None check for entity in batched delete query to prevent errors when entity list contains None values
Key Files Modified¶
type_bridge/generator/parser.py- Struct parsing supporttype_bridge/generator/render/- Struct code generationtype_bridge/generator/__main__.py---schema-pathCLI optiontype_bridge/crud/entity/manager.py- Batch operations, strict parametertype_bridge/crud/entity/query.py- Batch IID populationtype_bridge/crud/relation/manager.py- Role player IID population
[1.1.0] - 2025-12-19¶
New Features¶
Polymorphic Entity Instantiation¶
- Querying a supertype now returns proper subtype instances (Issue #65)
Artifact.manager(db).all()returns a mix ofUserStory,DesignAspect, etc.- Each entity has the correct Python type with all subtype-specific attributes populated
- IIDs and type information correctly extracted for each subtype
Usage Example:
# Define type hierarchy
class Artifact(Entity):
flags = TypeFlags(abstract=True)
name: Name = Flag(Key)
class UserStory(Artifact):
story_points: StoryPoints
class DesignAspect(Artifact):
priority: Priority
# Query supertype - get proper subtypes back
artifacts = Artifact.manager(db).all()
for artifact in artifacts:
print(type(artifact)) # UserStory, DesignAspect, etc.
print(artifact.name) # All have base attributes
if isinstance(artifact, UserStory):
print(artifact.story_points) # Subtype-specific attributes
Refactoring¶
Jinja2 Templates for Code Generation¶
- Code generator now uses Jinja2 templates instead of string concatenation
- 6 new templates: attributes, entities, relations, functions, package_init, registry
- Significant code reduction in render modules:
registry.py: 578 โ 156 lines (-422)package.py: 116 โ 61 lines (-55)entities.py: 234 โ 198 lines (-36)
Typer CLI¶
- Generator and migration CLIs migrated to Typer
- Improved help messages and command structure
- Better argument parsing and validation
Dependencies¶
- Added
jinja2>=3.1.0- Template engine for code generation - Added
typer>=0.15.0- CLI framework for generator and migration tools
Key Files Modified¶
type_bridge/crud/entity/manager.py- Polymorphic instantiation inget()type_bridge/crud/entity/query.py- Polymorphic instantiation inexecute()type_bridge/crud/utils.py-resolve_entity_class()utilitytype_bridge/generator/__main__.py- Typer CLItype_bridge/generator/render/- Jinja2 template integrationtype_bridge/generator/templates/- 6 new Jinja2 templatestype_bridge/migration/__main__.py- Typer CLI with subcommands
[1.0.1] - 2025-12-19¶
New Features¶
TypeDB IID Support¶
- Expose TypeDB Internal ID (IID) on entity and relation instances
_iidfield automatically populated when entities/relations are fetched from database- New
get_by_iid(iid: str)method on EntityManager and RelationManager - IID populated from
get(),filter().execute(), andall()operations
Usage Example:
# Insert entity
person = Person(name=Name("Alice"), age=Age(30))
Person.manager(db).insert(person)
# Fetch - IID is automatically populated
fetched = Person.manager(db).get(name="Alice")
print(fetched[0]._iid) # '0x1e00000000000000000000'
# Direct IID lookup
person = Person.manager(db).get_by_iid("0x1e00000000000000000000")
Bug Fixes¶
- Fixed relation IID assignment order - Set
_iidafter role player assignments to prevent Pydantic revalidation from resetting the value
Key Files Modified¶
type_bridge/session.py- IID extraction functionstype_bridge/crud/entity/manager.py-get_by_iid()methodtype_bridge/crud/entity/query.py- IID extraction from resultstype_bridge/crud/relation/manager.py-get_by_iid()methodtype_bridge/crud/relation/query.py- IID extraction from results
[1.0.0] - 2025-12-15¶
New Features¶
Django-style Migration System¶
- Complete migration framework for TypeDB schema evolution
- Auto-generate migrations from Python model changes
- Apply and rollback migrations with transaction safety
- Track migration state in TypeDB database
- CLI commands:
type-bridge makemigrations,type-bridge migrate -
Location:
type_bridge/migration/(2872 lines) -
Migration Operations
AddAttribute- Add new attribute typesAddEntity- Add new entity typesAddRelation- Add new relation types with rolesAddOwnership- Add attribute ownership to typesAddRolePlayer- Add role players to relationsRemoveAttribute,RemoveEntity,RemoveRelation- Remove typesRunTypeQL- Execute raw TypeQL for custom migrations- All operations support forward and rollback
-
Location:
type_bridge/migration/operations.py -
Migration Generator
- Auto-detect schema changes by comparing Python models to database
- Generate migration files with operations
- Support for incremental migrations (detect only changes)
-
Location:
type_bridge/migration/generator.py -
Migration Executor
- Apply pending migrations in order
- Rollback migrations in reverse order
- Dry-run mode for previewing changes
sqlmigratefor viewing generated TypeQL-
Location:
type_bridge/migration/executor.py -
Migration State Tracking
- Track applied migrations in TypeDB
-
Location:
type_bridge/migration/state.py -
Model Registry
- Register models for migration tracking
- Auto-discover models from modules
- Location:
type_bridge/migration/registry.py
Schema Introspection¶
- Query existing schema from TypeDB database
- Introspect entities, relations, attributes, and ownerships
- TypeDB 3.x compatible queries
- Model-aware introspection for efficient checking
- Location:
type_bridge/schema/introspection.py(527 lines)
Breaking Change Detection¶
- Analyze schema changes for safety
- Detect breaking vs safe changes
- Categories: BREAKING, SAFE, WARNING
- Check role player narrowing, type removal, etc.
- Location:
type_bridge/schema/breaking.py(411 lines)
Enhanced Schema Diff¶
- Improved schema comparison
- Compare by TypeDB type name instead of Python object identity
- Detect modified entities, relations, and role players
- Track attribute and ownership changes
- Location:
type_bridge/schema/info.py,type_bridge/schema/diff.py
Bug Fixes¶
TypeDB 3.x Compatibility¶
- Fixed schema comparison using Python object identity instead of type name
-
SchemaInfo.compare()now correctly matches entities/relations by type name -
Fixed migration executor to execute operations separately
-
TypeDB 3.x doesn't allow multiple
defineblocks in single query -
Fixed schema introspection to query ownership from schema definition
-
Uses
match {type_name} owns $a;for schema queries -
Fixed migration state tracking for TypeDB 3.x @key semantics
- Uses composite key (
migration_id) instead of dual@keyattributes
Testing¶
- All 391 integration tests passing
- Added comprehensive migration test suite
- Added role player diff tests
- Added schema introspection tests
Key Files Added¶
type_bridge/migration/__init__.py- Migration module exportstype_bridge/migration/__main__.py- CLI commandstype_bridge/migration/base.py- Migration base classtype_bridge/migration/operations.py- Migration operationstype_bridge/migration/generator.py- Auto-generationtype_bridge/migration/executor.py- Apply/rollbacktype_bridge/migration/loader.py- Load migration filestype_bridge/migration/state.py- State trackingtype_bridge/migration/registry.py- Model registrytype_bridge/schema/introspection.py- Schema introspectiontype_bridge/schema/breaking.py- Breaking change detectiontests/integration/migration/- Migration integration teststests/integration/schema/test_role_player_diff.py- Role player tests
Usage Example¶
from type_bridge.migration import MigrationGenerator, MigrationExecutor
from type_bridge import Database
db = Database("localhost:1729", "mydb")
# Generate migration from models
generator = MigrationGenerator(db, "./migrations")
generator.generate(models=[Person, Company], name="initial")
# Apply migrations
executor = MigrationExecutor(db, "./migrations")
results = executor.migrate()
# Rollback
executor.rollback()
CLI Usage¶
# Generate migrations
type-bridge makemigrations ./migrations --models myapp.models
# Apply migrations
type-bridge migrate ./migrations
# Show migration status
type-bridge showmigrations ./migrations
# Preview TypeQL
type-bridge sqlmigrate ./migrations 0001_initial
[0.9.4] - 2025-12-12¶
New Features¶
Debug Logging Support (Issue #43)¶
- Added comprehensive logging throughout TypeBridge using Python's standard
loggingmodule - See generated TQL queries during CRUD operations
- Hierarchical logger structure for fine-grained control
- Documentation:
docs/api/logging.md
Bug Fixes¶
Type Safety Improvements¶
- Fixed pyright errors for
TransactionType.nameaccess in session.py - Added
_tx_type_name()helper function for type-safe transaction type logging
Documentation¶
- Added
docs/api/logging.md- Comprehensive logging configuration guide - Updated
docs/DEVELOPMENT.mdwith logging section
Key Files Modified¶
type_bridge/session.py- Fixed type errors, added loggingtype_bridge/query.py- Added loggingtype_bridge/validation.py- Added loggingtype_bridge/schema/manager.py- Added loggingtype_bridge/schema/migration.py- Added loggingtype_bridge/crud/entity/manager.py- Added loggingtype_bridge/crud/entity/query.py- Added loggingtype_bridge/crud/entity/group_by.py- Added loggingtype_bridge/crud/relation/manager.py- Added loggingtype_bridge/crud/relation/query.py- Added loggingtype_bridge/crud/relation/group_by.py- Added loggingtype_bridge/generator/__main__.py- Added loggingtype_bridge/generator/render/attributes.py- Added loggingtype_bridge/generator/render/entities.py- Added loggingtype_bridge/generator/render/relations.py- Added loggingtype_bridge/models/entity.py- Added loggingtype_bridge/models/relation.py- Added loggingdocs/api/logging.md- New documentationdocs/DEVELOPMENT.md- Added logging section
[0.9.3] - 2025-12-12¶
Documentation¶
@key Attribute Requirement for update() (Issue #45)¶
- Added prominent documentation explaining that
update()requires @key attributes - New section "Important: @key Attributes Required for update()" in CRUD docs
- Clear examples showing proper
@keyattribute definition - Error scenarios documented: no
@keydefined,@keyvalue isNone - Guidance for UUID/ID fields as
@keyattributes - Cross-reference to Exception Handling section
- Location:
docs/api/crud.md(lines 369-413)
Key Files Modified¶
docs/api/crud.md- Added @key requirement documentation in Update Operations section
[0.9.2] - 2025-12-12¶
New Features¶
KeyAttributeError Exception (Issue #44)¶
- Added
KeyAttributeErrorexception for @key validation failures - Raised when @key attribute is None during update/delete
- Raised when no @key attributes are defined on entity
- Structured attributes:
entity_type,operation,field_name,all_fields - Helpful error messages with hints for fixing issues
- Inherits from
ValueErrorfor backward compatibility - Location:
type_bridge/crud/exceptions.py
Testing¶
- Added 7 unit tests for
KeyAttributeError - 813 unit tests passing
Key Files Added/Modified¶
type_bridge/crud/exceptions.py- AddedKeyAttributeErrorclasstype_bridge/crud/__init__.py- ExportKeyAttributeErrortype_bridge/__init__.py- ExportKeyAttributeErrorin public APItype_bridge/crud/entity/manager.py- UseKeyAttributeErrortype_bridge/crud/entity/query.py- UseKeyAttributeErrortests/unit/exceptions/test_exceptions.py- Added KeyAttributeError tests
Usage Example¶
from type_bridge import KeyAttributeError
try:
manager.update(entity_with_none_key)
except KeyAttributeError as e:
print(f"Entity: {e.entity_type}")
print(f"Operation: {e.operation}")
print(f"Field: {e.field_name}")
[0.9.1] - 2025-12-11¶
New Features¶
Enhanced Code Generator (PR #53)¶
- Registry Module - Generates
registry.pywith schema metadata as Python dictionaries - Entity/relation attributes, roles, and inheritance info
- JSON Schema fragments for validation
- Convenience lookup functions
- Schema hash for change detection
-
Location:
type_bridge/generator/render/registry.py -
Enhanced Function Generation - Generic
FunctionCallExpr[T]with precise return type hints - Support for all TypeDB function variations: stream, scalar, tuple, optional returns
- Added
boolto type mapping - Improved docstrings with return type documentation
-
Location:
type_bridge/generator/render/functions.py -
TypeQL Parser Enhancements
@independentattribute flag support@range(min..max)constraint parsing (integers, floats, dates, datetimes, open-ended)@cardonplaysdeclarations with inheritance@cardonrelatesdeclarations//C-style comments alongside#comments- Comment annotations parsing (
@prefix,@tags, etc.) - Location:
type_bridge/generator/parser.py,type_bridge/generator/typeql.lark
Testing¶
- Added comprehensive generator unit tests for annotations, functions, and registry
- 1,268 total tests passing
Key Files Added/Modified¶
type_bridge/generator/render/registry.py- Registry module generation (new)type_bridge/generator/annotations.py- Annotation parsing (new)type_bridge/generator/render/functions.py- Enhanced function generationtype_bridge/generator/parser.py- Parser enhancementstype_bridge/generator/typeql.lark- Grammar updatestype_bridge/generator/models.py- New annotation modelstype_bridge/expressions/functions.py- Generic FunctionCallExprdocs/api/generator.md- Updated documentation
Contributors¶
- @CaliLuke - Generator enhancements
[0.9.0] - 2025-12-11¶
New Features¶
Type-Safe Role Player Expressions (PR #42)¶
- Type-safe role player field expressions
- Access role player attributes with type safety:
Employment.employee.age.gte(Age(30)) RoleRefclass for class-level role accessRolePlayerFieldReffor type-safe attribute accessRolePlayerNumericFieldReffor numeric comparison methodsRolePlayerStringFieldReffor string-specific methods (contains, like, regex)-
Location:
type_bridge/fields/role.py -
Django-style role-player lookup filters
- Filter by role player attributes:
filter(employee__age__gt=30) - Support for comparison operators:
__eq,__gt,__lt,__gte,__lte - Support for string operators:
__contains,__like,__regex -
Location:
type_bridge/crud/relation/lookup.py -
Added
order_by()method to EntityQuery and RelationQuery - Sort results by entity/relation attributes or role player attributes
- Supports ascending (default) and descending (
-field) order - Role-player sorting:
order_by('employee__age', '-salary') -
Location:
type_bridge/crud/entity/query.py,type_bridge/crud/relation/query.py -
Added public
Relation.get_roles()method - Clean API for accessing relation roles without internal
_rolesaccess - Returns:
dict[str, Role]mapping role names to Role instances - Location:
type_bridge/models/relation.py
Bug Fixes¶
- Fixed
RelationQuery.filter()to support Django-style kwargs - Chained
.filter()calls now properly support**filtersparameter - Location:
type_bridge/crud/relation/query.py
Testing¶
- Added
TestCombinedWithPaginationintegration tests - Added
TestRoleMultiAttributeAccessunit tests - All type checks pass without suppressions (uses
isinstancefor type narrowing) - 806 unit tests + 377 integration tests = 1,183 total tests
Key Files Added/Modified¶
type_bridge/fields/role.py- RoleRef and RolePlayerFieldRef classestype_bridge/crud/relation/lookup.py- Django-style lookup parsertype_bridge/crud/relation/query.py- RelationQuery with filter and order_bytype_bridge/crud/entity/query.py- EntityQuery with order_bytype_bridge/models/relation.py- Added get_roles() methodtype_bridge/generator/render/relations.py- Updated generated code patternstests/unit/fields/test_role_ref.py- RoleRef unit teststests/integration/queries/test_role_field_expressions.py- Integration tests
Usage Examples¶
from type_bridge import Relation, Role, Entity, TypeFlags, String, Integer
class Age(Integer):
pass
class Name(String):
pass
class Person(Entity):
flags = TypeFlags(name="person")
name: Name = Flag(Key)
age: Age | None = None
class Employment(Relation):
flags = TypeFlags(name="employment")
employee: Role[Person] = Role("employee", Person)
# Type-safe role player expression
results = Employment.manager(db).filter(
Employment.employee.age.gte(Age(30))
).execute()
# Django-style lookup
results = Employment.manager(db).filter(employee__age__gt=30).execute()
# Combined with sorting and pagination
results = (
Employment.manager(db)
.filter(Employment.employee.age.gte(Age(25)), salary__gte=80000)
.order_by("employee__age", "-salary")
.limit(10)
.execute()
)
[0.8.1] - 2025-12-11¶
New Features¶
TypeDB Function Support in Code Generator¶
- Parse TypeQL
fundeclarations with parameters and return types - Generate Python function wrappers that return
FunctionCallExprobjects - Auto-generate
functions.pymodule when functions are defined in schema - Support for all TypeDB data types (string, integer, date, datetime, double, boolean, decimal, duration)
-
Location:
type_bridge/generator/render/functions.py -
Added
FunctionCallExprclass for building function calls in queries - New expression type for calling TypeDB functions
- Location:
type_bridge/expressions/functions.py
Lark-based Parser¶
- Migrated from regex-based parser to robust Lark grammar
- Added formal grammar file (
typeql.lark) for better maintainability - Improved handling of edge cases (whitespace, optional clauses)
- Better support for TypeDB 3.0 features
- Location:
type_bridge/generator/typeql.lark,type_bridge/generator/parser.py
Bug Fixes¶
Parser Grammar Fixes¶
- Fixed parsing of
suband@abstractin entity/relation bodies - Now correctly handles patterns like
entity page @abstract, sub content, - Supports
subappearing anywhere in the type definition, not just at the start - Fixed parsing of
@cardannotations onplaysandrelatesstatements - Now correctly parses
plays posting:post @card(1)andrelates subject @card(1)
Testing¶
- Added 136 new unit tests for function parsing and rendering
- All 808 tests passing (520 unit + 288 integration)
Key Files Added/Modified¶
type_bridge/generator/typeql.lark- Formal TypeQL grammar (75 lines)type_bridge/generator/parser.py- Rewritten with Lark integrationtype_bridge/generator/models.py- AddedFunctionSpec,ParameterSpectype_bridge/generator/render/functions.py- Function code generationtype_bridge/expressions/functions.py-FunctionCallExprclasstype_bridge/expressions/__init__.py- ExportFunctionCallExprtype_bridge/generator/__init__.py- Expose function parsing APItests/unit/generator/test_functions.py- Function unit tests
[0.8.0] - 2025-12-11¶
New Features¶
Code Generator (TypeQL โ Python)¶
- Added
type_bridge.generatormodule for generating Python models from TypeQL schema files - Eliminates manual synchronization between
.tqlschemas and Python code - Write schema once in TypeQL, generate type-safe Python models automatically
-
Location:
type_bridge/generator/ -
CLI interface for code generation
- Usage:
python -m type_bridge.generator schema.tql -o ./models/ - Options:
--version,--no-copy-schema,--implicit-keys -
Location:
type_bridge/generator/__main__.py -
Programmatic API
generate_models(schema, output_dir)- Main generation functionparse_tql_schema(schema_content)- Parse TypeQL to intermediate representation-
Location:
type_bridge/generator/__init__.py -
Full TypeDB 3.x schema support
- All value types: string, integer, double, decimal, boolean, date, datetime, datetime-tz, duration
- Entity and relation inheritance (
subdeclarations) - Abstract types (
@abstract) - Attribute constraints:
@key,@unique,@card,@regex,@values - Role definitions and
playsdeclarations -
Comment annotations for customization (
# @prefix:,# @internal) -
Generated package structure
Bug Fixes¶
Optional Attribute Update Fix¶
- Fixed silent update failures for optional attributes (Resolves #47)
- Previously: Updating an entity with an optional attribute set to
Nonecould silently fail - Now: Properly handles
Nonevalues in update operations - Location:
type_bridge/crud/entity/manager.py
Testing¶
- Added comprehensive generator test suite
- 62 unit tests covering parser, naming utilities, and renderers
- 18 integration tests verifying generated code imports and executes correctly
- Test fixtures with complex TypeQL schemas
-
Location:
tests/unit/generator/,tests/integration/generator/ -
Expanded lookup filter tests
- Additional test coverage for lookup filter parsing and execution
- Location:
tests/unit/crud/test_lookup_parser.py,tests/integration/queries/test_lookup_filters.py
Documentation¶
- Added generator documentation
- Complete API reference and usage guide
- CLI reference and examples
- Supported TypeQL features and cardinality mapping
- Best practices for generated code management
-
Location:
docs/api/generator.md -
Updated project documentation
- Added generator to project structure in CLAUDE.md
- Updated README.md with code generator feature
Key Files Added/Modified¶
type_bridge/generator/__init__.py- Public API:generate_models(),parse_tql_schema()type_bridge/generator/__main__.py- CLI interfacetype_bridge/generator/models.py-ParsedSchema,AttributeSpec,EntitySpec,RelationSpectype_bridge/generator/parser.py- TypeQL parser with inheritance resolutiontype_bridge/generator/naming.py- kebab-case โ PascalCase/snake_case utilitiestype_bridge/generator/render/- Code generation renderers (attributes, entities, relations, package)type_bridge/crud/entity/manager.py- Optional attribute update fixdocs/api/generator.md- Generator documentation
Usage Examples¶
CLI Usage¶
# Generate models from a schema file
python -m type_bridge.generator schema.tql -o ./myapp/models/
# With options
python -m type_bridge.generator schema.tql \
--output ./myapp/models/ \
--version 2.0.0 \
--implicit-keys id
Programmatic Usage¶
from type_bridge.generator import generate_models
# From a file path
generate_models("schema.tql", "./myapp/models/")
# From schema text
schema = """
define
entity person, owns name @key;
attribute name, value string;
"""
generate_models(schema, "./myapp/models/")
Using Generated Models¶
from myapp.models import attributes, entities, relations
from myapp.models import SCHEMA_VERSION, schema_text
# Access generated classes
person = entities.Person(name=attributes.Name("Alice"))
# Get schema version
print(SCHEMA_VERSION) # "1.0.0"
[0.7.2] - 2025-12-10¶
Breaking Changes¶
New Exceptions for Delete Operations¶
- Added
EntityNotFoundError- Raised when deleting an entity that doesn't exist - Now raised for both keyed and keyless entities when no match is found
- Previously: keyed entities silently succeeded, keyless raised
ValueError -
Subclass of
LookupError -
Added
RelationNotFoundError- Raised when deleting a relation that doesn't exist - Raised when relation with given role players is not found
- Previously: silently succeeded
-
Subclass of
LookupError -
Added
NotUniqueError- Raised when keyless entity matches multiple records - Replaces
ValueErrorfor multiple match scenarios - Subclass of
ValueError - Suggestion to use
filter().delete()for bulk deletion
Migration Guide¶
# Handling non-existent entity deletion (NEW in v0.7.2)
from type_bridge import EntityNotFoundError, RelationNotFoundError, NotUniqueError
# Entity with @key that doesn't exist
try:
manager.delete(nonexistent_entity)
except EntityNotFoundError:
print("Entity was already deleted or never existed")
# Relation that doesn't exist
try:
relation_manager.delete(nonexistent_relation)
except RelationNotFoundError:
print("Relation was already deleted or never existed")
# Entity without @key matching multiple records
try:
manager.delete(keyless_entity)
except NotUniqueError:
print("Multiple entities matched - use filter().delete() for bulk deletion")
# Bulk delete with __in (migrating from v0.7.0)
# OLD: manager.delete_many(name__in=["Alice", "Bob"])
# NEW:
count = manager.filter(name__in=["Alice", "Bob"]).delete()
Key Files Modified¶
type_bridge/crud/exceptions.py- NEW - Exception classestype_bridge/crud/__init__.py- Export exceptionstype_bridge/crud/entity/manager.py- Add existence check before deletetype_bridge/crud/relation/manager.py- Add existence check before deletetype_bridge/__init__.py- Export exceptions
[0.7.1] - 2025-12-09¶
Breaking Changes¶
Delete API Refactored to Instance-Based Pattern¶
- Changed
EntityManager.delete()signature - Old:
delete(**filters) -> int(filter-based, returns count) - New:
delete(entity: E) -> E(instance-based, returns deleted entity) - Uses
@keyattributes to identify entity (same pattern asupdate()) -
Related: Issue #37
-
Changed
EntityManager.delete_many()signature - Old:
delete_many(**filters) -> int(filter-based with__insupport) -
New:
delete_many(entities: list[E]) -> list[E](instance list, returns list) -
Changed
RelationManager.delete()anddelete_many()similarly - Uses role players'
@keyattributes to identify the relation - Each role player is matched by their
@keyattribute
New Features¶
Instance Delete Methods¶
- Added
Entity.delete(connection)instance method - Delete entity directly:
alice.delete(db) - Returns self for chaining
-
Location:
type_bridge/models/entity.py -
Added
Relation.delete(connection)instance method - Delete relation directly:
employment.delete(db) - Returns self for chaining
- Location:
type_bridge/models/relation.py
Fallback for Entities Without @key¶
- Entities without
@keycan still be deleted if they match exactly 1 record - Matches by ALL non-None attributes
- Raises
ValueErrorif 0 or >1 matches found - Provides safer delete behavior than filter-based approach
Migration Guide¶
# OLD (v0.7.0): Filter-based deletion
deleted_count = manager.delete(name="Alice") # Returns int
# NEW (v0.7.1): Instance-based deletion
alice = manager.get(name="Alice")[0]
deleted = manager.delete(alice) # Returns Alice instance
# OR use instance method
alice.delete(db) # Returns alice
# For filter-based deletion, use filter().delete()
count = manager.filter(name__in=["Alice", "Bob"]).delete() # Still returns int
count = manager.filter(Age.gt(Age(65))).delete() # Expression filters
Key Files Modified¶
type_bridge/crud/entity/manager.py- Refactoreddelete(),delete_many()type_bridge/crud/relation/manager.py- Refactoreddelete(),delete_many()type_bridge/models/entity.py- Addeddelete()instance methodtype_bridge/models/relation.py- Addeddelete()instance method
[0.7.0] - 2025-12-08¶
๐ New Features¶
TransactionContext for Shared Operations¶
- Added
TransactionContextclass for sharing transactions across operations - Multiple managers can share a single transaction
- Auto-commit on context exit, rollback on exception
- Location:
type_bridge/session.py
with db.transaction(TransactionType.WRITE) as tx:
person_mgr = Person.manager(tx) # reuses tx
artifact_mgr = Artifact.manager(tx) # same tx
# ... operations commit together
Unified Connection Type¶
- Added
Connectiontype alias for flexible connection handling Connection = Database | Transaction | TransactionContext- All managers accept any Connection type
ConnectionExecutorhandles transaction reuse internally- Location:
type_bridge/session.py
Entity Dict Helpers¶
- Added
Entity.to_dict()for serialization - Unwraps Attribute instances to
.value - Supports
include,exclude,by_alias,exclude_unsetoptions - Added
Entity.from_dict()for deserialization - Optional
field_mappingfor external key names strict=Falsemode to ignore unknown fields- Location:
type_bridge/models/entity.py
person.to_dict() # {'name': 'Alice', 'age': 30}
Person.from_dict(payload, field_mapping={"display-id": "display_id"})
Django-style Lookup Filters¶
- Added lookup suffix operators to
filter() __contains,__startswith,__endswith,__regexfor strings__gt,__gte,__lt,__ltefor comparisons__infor disjunction (multiple values)__isnullfor null checks- Location:
type_bridge/crud/entity/manager.py
person_manager.filter(name__startswith="Al", age__gt=30).execute()
person_manager.filter(status__in=["active", "pending"]).execute()
Bulk Operations¶
- Added
EntityManager.update_many()- Update multiple entities in one transaction - Added
EntityManager.delete_many()- Bulk delete with__infilter support
๐ Documentation¶
- Comprehensive documentation update
- Fixed broken example paths in README.md
- Added Connection types documentation to docs/api/crud.md
- Added TransactionContext usage examples
- Added lookup filter documentation with TypeQL mappings
- Added dict helpers documentation to docs/api/entities.md
๐ง Maintenance¶
- Fixed version mismatch between pyproject.toml and init.py
- Added
typings/stubs forisodateandtypedb.driver
๐ฆ Key Files Modified¶
type_bridge/session.py- Added TransactionContext, Connection, ConnectionExecutortype_bridge/models/entity.py- Added to_dict(), from_dict()type_bridge/crud/entity/manager.py- Added lookup filters, update_many, delete_manytype_bridge/crud/relation/manager.py- Unified connection handlingdocs/api/crud.md- New sections for transactions, lookups, bulk opsdocs/api/entities.md- Dict helpers documentation
[0.6.4] - 2025-12-04¶
๐ New Features¶
CRUD PUT Operations (Idempotent Insert)¶
- Added
EntityManager.put()for idempotent entity insertion - Inserts entity only if it doesn't already exist
- Safe to call multiple times without creating duplicates
- Uses TypeQL's PUT clause for atomic match-or-insert semantics
-
Location:
type_bridge/crud/entity/manager.py -
Added
EntityManager.put_many()for bulk idempotent insertion - All-or-nothing semantics: entire pattern must match or all is inserted
-
Efficient batch operations for data synchronization
-
Added
RelationManager.put()for idempotent relation insertion - Same PUT semantics for relations with role players
- Prevents duplicate relationships
-
Location:
type_bridge/crud/relation/manager.py -
Added
RelationManager.put_many()for bulk relation PUT - Batch idempotent insertion for relations
Use Cases¶
- Data import scripts (safe re-runs)
- Ensuring reference data exists
- Synchronization with external systems
- Idempotent API endpoints
๐ Documentation¶
- Updated
docs/api/crud.mdwith PUT operations section - Comparison table: INSERT vs PUT behavior
- All-or-nothing semantics explanation
-
Usage examples for entities and relations
-
Added
examples/basic/crud_08_put.pytutorial - Demonstrates PUT vs INSERT differences
- Shows idempotent behavior patterns
๐งช Testing¶
- Added entity PUT integration tests (
tests/integration/crud/entities/test_put.py) - Single put, bulk put_many
- Idempotency verification
-
All-or-nothing behavior
-
Added relation PUT integration tests (
tests/integration/crud/relations/test_put.py) - Relation put operations
- Role player handling
๐ฆ Key Files Modified¶
type_bridge/crud/entity/manager.py- Addedput(),put_many()type_bridge/crud/relation/manager.py- Addedput(),put_many()docs/api/crud.md- PUT documentationexamples/basic/crud_08_put.py- New tutorialtests/integration/crud/entities/test_put.py- Entity PUT teststests/integration/crud/relations/test_put.py- Relation PUT testsREADME.md- Updated features
๐ก Usage Examples¶
# Single PUT (idempotent insert)
alice = Person(name=Name("Alice"), age=Age(30))
person_manager.put(alice)
person_manager.put(alice) # No duplicate created
# Bulk PUT
persons = [Person(name=Name("Bob")), Person(name=Name("Carol"))]
person_manager.put_many(persons)
person_manager.put_many(persons) # No duplicates
# Relation PUT
employment = Employment(employee=alice, employer=techcorp)
employment_manager.put(employment)
[0.6.3] - 2025-12-04¶
๐ New Features¶
Multi-Player Roles¶
- Added
Role.multi()for roles playable by multiple entity types - Syntax:
origin: Role[Document | Email] = Role.multi("origin", Document, Email) - Eliminates need for artificial supertype hierarchies
- Generates multiple
playsdeclarations in TypeQL schema - Location:
type_bridge/models/role.py - Full CRUD support for multi-role relations
- Filter by specific player type:
manager.get(origin=doc) - Chainable operations work with multi-roles
- Batch insert with mixed player types supported
- Runtime validation: TypeError if wrong player type assigned
- Pydantic integration: Union types provide IDE/type-checker support
TypeDB 3.7 Compatibility¶
- Verified compatibility with TypeDB 3.7.0-rc0
- Updated documentation to reflect tested TypeDB version
๐ Bug Fixes¶
Inherited Attribute Filter Bug¶
- Fixed filters on inherited attributes being silently ignored
- Root cause:
get_owned_attributes()was used instead ofget_all_attributes()in filter operations - Affected methods:
EntityManager.delete(),EntityQuery.delete(),QueryBuilder.match_entity() - Example:
Dog.manager(db).get(name=LivingName("Buddy"))now works whennameis inherited from parentLivingclass - Location:
type_bridge/crud/entity/query.py:215,type_bridge/crud/entity/manager.py:219,type_bridge/query.py:193 - Impact: Dictionary-based filters (
get(),delete()) now correctly handle inherited attributes in subtype queries
๐งช Testing¶
Multi-Role Tests¶
- Multi-role integration tests (
tests/integration/crud/relations/test_multi_role.py) - 37 tests - Insert relations with different role player types
- Filter by multi-role players
- Delete filtered by multi-role
- Chainable
update_withoperations - Multi-role with 3+ entity types
- Multi-role unit tests (
tests/unit/core/test_multi_role_players.py) - Role.multi() API validation
- Type safety and runtime validation
Inherited Attribute Filter Tests¶
- Created unit tests (
tests/unit/core/test_inherited_attribute_filter.py) with 9 tests: get_owned_attributes()vsget_all_attributes()behavior verificationQueryBuilder.match_entity()with inherited/owned/mixed attribute filters- Deep inheritance chain (grandparent โ parent โ child) attribute access
- Created integration tests (
tests/integration/crud/test_inherited_attribute_filter.py) with 5 tests: get()with inherited key attributedelete()with inherited attribute filter- Combined inherited + owned attribute filters
๐ฆ Key Files Modified¶
type_bridge/models/role.py- AddedRole.multi()and multi-player supporttype_bridge/schema/info.py- Generate multipleplaysdeclarationstype_bridge/crud/relation/manager.py- Multi-role query handlingtype_bridge/crud/relation/query.py- Multi-role filtering supportdocs/api/relations.md- Added "Multi-player Roles" documentationtype_bridge/crud/entity/query.py- Fixeddelete()to useget_all_attributes()type_bridge/crud/entity/manager.py- Fixeddelete()to useget_all_attributes()type_bridge/query.py- Fixedmatch_entity()to useget_all_attributes()tests/integration/crud/relations/test_multi_role.py- New multi-role test suite (37 tests)tests/unit/core/test_multi_role_players.py- New multi-role unit tests
[0.6.0] - 2025-11-24¶
๐ New Features¶
Chainable Delete and Update Operations¶
- Added
EntityQuery.delete()for chainable deletion - Delete entities after complex filtering:
manager.filter(Age.gt(Age(65))).delete() - Builds TypeQL delete query from both dict-based and expression-based filters
- Single atomic transaction with automatic rollback on error
- Returns count of deleted entities (0 if no matches)
-
Location:
type_bridge/crud.py:626-676 -
Added
EntityQuery.update_with(func)for functional bulk updates - Update multiple entities using lambda or named functions
- Example:
manager.filter(Age.gt(Age(30))).update_with(lambda p: setattr(p, 'age', Age(p.age.value + 1))) - Fetches matching entities, applies function, updates all in single transaction
- Returns list of updated entities (empty list if no matches)
- Error handling: Stops immediately and raises error if function fails on any entity
- All updates in single atomic transaction (all-or-nothing)
-
Location:
type_bridge/crud.py:678-730 -
Helper methods added
_build_update_query(entity): Builds TypeQL update query for single entity_is_multi_value_attribute(flags): Checks attribute cardinality- Reuses existing EntityManager logic for consistency
Benefits¶
- Chainable API: Natural method chaining for complex operations
- Type-safe: Full integration with expression-based filtering
- Atomic transactions: All operations are all-or-nothing
- Functional updates: Clean lambda/function-based bulk updates
- Consistent API: Works seamlessly with existing filter() method
AttributeFlags Configuration for Attribute Type Names¶
- Added
AttributeFlags.namefield - Explicitly override attribute type name:
flags = AttributeFlags(name="person_name") - Use case: Interop with existing TypeDB schemas, legacy naming conventions
-
Location:
type_bridge/attribute/flags.py:229 -
Added
AttributeFlags.casefield - Apply case formatting to attribute type names:
flags = AttributeFlags(case=TypeNameCase.SNAKE_CASE) - Supports: CLASS_NAME (default), LOWERCASE, SNAKE_CASE, KEBAB_CASE
- Use case: Consistent naming conventions across large schemas
-
Location:
type_bridge/attribute/flags.py:230 -
Updated
Attribute.__init_subclass__to use AttributeFlags - Priority: flags.name > attr_name > flags.case > class.case > default CLASS_NAME
- Respects both explicit name and case formatting
- Location:
type_bridge/attribute/base.py:108-126
Benefits¶
- Flexible naming: Support for legacy schemas and naming conventions
- Consistent API: Mirrors TypeFlags.name pattern for entities/relations
- Migration friendly: Easier interop with existing TypeDB databases
- Developer choice: Explicit name or automatic case formatting
๐๏ธ Refactoring¶
Modularized CRUD Operations¶
- Refactored monolithic
crud.py(3008 lines) into modular structure - Split into 11 focused modules under
crud/directory - Entity operations:
crud/entity/with manager, query, and group_by modules - Relation operations:
crud/relation/with manager, query, and group_by modules - Shared utilities:
crud/utils.pyforformat_valueandis_multi_value_attribute - Base definitions:
crud/base.pyfor type variables - Benefits:
- Eliminated code duplication (shared utilities now have single implementations)
- Improved maintainability (files are now 200-800 lines each)
- Better code organization and discoverability
- Preserved backward compatibility (all imports still work)
- Impact: No breaking changes, all existing code continues to work
Modularized Models¶
- Previously refactored
models.pyinto modular structure - Split into
models/directory with base, entity, relation, role, and utils modules - Improved separation of concerns and maintainability
๐ Bug Fixes¶
String Attribute Escaping in Multi-Value Attributes¶
- Fixed proper escaping of special characters in multi-value string attributes
- Backslashes are now properly escaped:
\โ\\ - Double quotes are properly escaped:
"โ\" - Escape order matters: backslashes first, then quotes
- Location:
type_bridge/query.py,type_bridge/crud.py,type_bridge/models/base.py - Impact: Multi-value string attributes with quotes or backslashes now work correctly in insert/update operations
- Examples:
- Quotes:
Tag('skill "Python"')โ TypeQL:has Tag "skill \"Python\"" - Backslashes:
Path("C:\\Users\\Alice")โ TypeQL:has Path "C:\\Users\\Alice" - Mixed:
Description(r'Path: "C:\Program Files"')โ TypeQL:has Description "Path: \"C:\\Program Files\""
๐ Documentation¶
API Documentation Updated¶
- Updated
docs/api/crud.mdwith comprehensive new sections: - Chainable Delete section with examples and behavior explanation
- Bulk Update with Function section demonstrating lambda and named function usage
- Updated EntityQuery method signatures
- Added "New in v0.6.0" markers for discoverability
-
Error handling and empty results behavior documented
-
Updated
docs/api/attributes.mdwith new section: - "Configuring Attribute Type Names" section with comprehensive examples
- Documents AttributeFlags.name for explicit type name overrides
- Documents AttributeFlags.case for automatic case formatting
- Shows priority order and all configuration options
-
Use cases and best practices
-
Updated
docs/INTERNALS.md: - Updated AttributeFlags dataclass documentation
- Added name and case fields with usage examples
- Updated cardinality field names (card_min, card_max)
README Updated¶
- Added "Chainable Operations" to features list
- Highlights filter, delete, and bulk update capabilities
- Location:
README.md
New Example Created¶
- Created
examples/advanced/crud_07_chainable_operations.py - Comprehensive demonstration of chainable delete and update
- Shows lambda functions, named functions, and complex multi-attribute updates
- Demonstrates atomic transaction behavior with rollback examples
- Interactive tutorial format with step-by-step explanations
๐งช Testing¶
Integration Tests Added¶
- Created
tests/integration/crud/entities/test_chainable.pywith 9 comprehensive tests: test_chainable_delete_with_expression_filter- Basic delete with expressionstest_chainable_delete_with_multiple_filters- Multiple filter combinationstest_chainable_delete_returns_zero_for_no_matches- Empty results handlingtest_chainable_delete_with_range_filter- Range queries (gte/lt)test_update_with_lambda_increments_age- Lambda function updatestest_update_with_function_modifies_status- Named function updatestest_update_with_returns_empty_list_for_no_matches- Empty results handlingtest_update_with_complex_function_multiple_attributes- Multi-attribute updatestest_update_with_atomic_transaction- Transaction rollback verification
Test Results¶
- All 9 tests passing โ
- Tests verify:
- Correct entity deletion with expression filters
- Accurate counts returned
- Proper transaction boundaries (atomic behavior)
- Error propagation and rollback
- Empty result handling
- Multi-attribute updates
- Lambda and function-based updates
Escaping Test Coverage Added¶
- Created comprehensive string escaping test suite
- 7 unit tests for multi-value string escaping patterns
- 9 integration tests verifying end-to-end escaping behavior
- Location:
tests/unit/attributes/test_multivalue_escaping.py,tests/integration/crud/attributes/test_multivalue_escaping.py - Test coverage includes:
- Quotes in strings:
'skill "Python"' - Backslashes in paths:
C:\Users\Alice - Mixed escaping:
"C:\Program Files\App" - Empty strings and special characters
- Unicode characters (cafรฉ, ๆฅๆฌ่ช, emoji๐)
- Single quotes (not escaped in TypeQL)
- Relations with multi-value escaping
- Batch operations:
insert_many(),update_with()
๐ฆ Key Files Modified¶
type_bridge/crud.py- Added delete() and update_with() to EntityQuery classdocs/api/crud.md- Updated API documentation with new methodsREADME.md- Added chainable operations to features listexamples/advanced/crud_07_chainable_operations.py- New comprehensive exampletests/integration/crud/entities/test_chainable.py- New integration test suitetests/unit/attributes/test_multivalue_escaping.py- New unit test suite (7 tests)tests/integration/crud/attributes/test_multivalue_escaping.py- New integration test suite (9 tests)
๐ก Usage Examples¶
Chainable Delete¶
# Delete all persons over 65
count = Person.manager(db).filter(Age.gt(Age(65))).delete()
# Delete with multiple filters
count = manager.filter(
Age.lt(Age(18)),
Status.eq(Status("inactive"))
).delete()
Chainable Update with Lambda¶
# Increment age for all persons over 30
updated = manager.filter(Age.gt(Age(30))).update_with(
lambda person: setattr(person, 'age', Age(person.age.value + 1))
)
Chainable Update with Function¶
def promote(person):
person.status = Status("senior")
person.salary = Salary(int(person.salary.value * 1.1))
promoted = manager.filter(Age.gte(Age(35))).update_with(promote)
[0.5.1] - 2025-11-20¶
๐ Bug Fixes¶
Integer Key Query Bug¶
- Fixed entities with Integer-type keys failing to query by key value
- Root cause: Attribute instances not being unwrapped before TypeQL value formatting
EntityId(123)was formatted as"123"(string) instead of123(integer)- Generated incorrect TypeQL:
has EntityId "123"causing type mismatch - Fix: Added
.valueextraction in_format_value()before type checking - Location:
type_bridge/query.py:252-256,type_bridge/crud.py:419-423,type_bridge/crud.py:1145-1149 - Impact: All non-string attribute types (Integer, Double, Decimal, Boolean, Date, DateTime, DateTimeTZ, Duration) now work correctly as entity keys and in query filters
- Silent failure fixed: Entities would insert successfully but couldn't be queried, now both work correctly
๐งช Testing¶
Regression Tests Added¶
- Created comprehensive Integer key test suite
- 5 new integration tests specifically for Integer key bug regression
- Tests cover: basic insert/query, comparison with String keys, various integer values, chainable queries, all()/count() methods
- Location:
tests/integration/crud/entities/test_integer_key_bug.py - Test Results: 422/422 tests passing (284 unit + 138 integration) โ
- All existing tests still passing
- All new regression tests passing
- Zero test failures or regressions
Why String Keys Worked¶
- String attributes need quotes in TypeQL anyway
- Bug accidentally produced correct output:
"KEY-123" - Integer, Boolean, Double, etc. require unquoted values in TypeQL
- These would fail with incorrect quoting:
"123","true","3.14"
๐ฆ Key Files Modified¶
type_bridge/query.py- Fixed_format_value()functiontype_bridge/crud.py- FixedEntityManager._format_value()andRelationManager._format_value()tests/integration/crud/entities/test_integer_key_bug.py- New regression test suite (5 tests)
[0.5.0] - 2025-11-20¶
๐ New Features¶
Concise Attribute Type-Based Expression API¶
- New streamlined query API using attribute class methods
- Old:
Person.age.gt(Age(30))โ New:Age.gt(Age(30))โจ - Shorter, more readable syntax with better type checking support
- Type checkers now correctly validate all expression methods
- Location:
type_bridge/attribute/base.py,type_bridge/attribute/string.py
Class Methods Added to Attribute Base Class¶
- Comparison methods:
gt(),lt(),gte(),lte(),eq(),neq() - Example:
Age.gt(Age(30)),Salary.gte(Salary(80000)) - Aggregation methods:
sum(),avg(),max(),min(),median(),std() - Example:
Salary.avg(),Age.sum() - String-specific methods (on
Stringclass):contains(),like(),regex() - Example:
Email.contains(Email("@company.com")),Name.like(Name("^A.*"))
Runtime Validation¶
- Automatic attribute ownership validation in filter() methods
- Validates that entity owns the attribute type being queried
- Raises
ValueErrorwith helpful message if validation fails - Example:
person_manager.filter(Salary.gt(Salary(50000)))validates Person owns Salary - Location:
type_bridge/crud.py,type_bridge/expressions/base.py
๐ API Changes¶
Expression Classes Refactored¶
- Changed from field-based to attribute type-based
ComparisonExpr,StringExpr,AggregateExprnow useattr_typeinstead offield- Simpler internal structure with 1-to-1 mapping (attribute type uniquely identifies field)
- Location:
type_bridge/expressions/comparison.py,type_bridge/expressions/string.py,type_bridge/expressions/aggregate.py
Backwards Compatibility¶
- Old field-based API still works
Person.age.gt(Age(30))continues to work alongside new API- FieldRef classes now delegate to attribute class methods internally
- Gradual migration path for existing code
- Location:
type_bridge/fields.py
๐ง Type Safety Improvements¶
Keyword-Only Arguments Enforced¶
- Changed
@dataclass_transform(kw_only_default=False)โTrue - All Entity/Relation constructors now require keyword arguments for clarity and safety
- Improves code readability and prevents positional argument order errors
- Example:
Person(name=Name("Alice"), age=Age(30))โ - Positional args now rejected by type checkers:
Person(Name("Alice"), Age(30))โ - Location:
type_bridge/models/base.py:20,type_bridge/models/entity.py:81,type_bridge/models/relation.py:30
Optional Field Defaults Required¶
- Added explicit
= Nonedefaults for all optional fields - Pattern:
age: Age | None = None(previouslyage: Age | None) - Makes field optionality explicit in code for better clarity
- Improves IDE autocomplete and type checking accuracy
- Required by
kw_only_default=Trueto distinguish optional from required fields - Applied throughout codebase: examples, tests, integration tests
Pyright Type Checking Configuration¶
- Added
pyrightconfig.jsonfor project-wide type checking - Excludes validation tests from type checking (
tests/unit/type-check-except/) - Tests intentionally checking Pydantic validation failures now properly excluded
- Core library achieves 0 errors, 0 warnings, 0 informations โจ
- Proper separation of type-safe code vs runtime validation tests
- Location:
pyrightconfig.json(new file)
Validation Tests Reorganized¶
- Moved intentional validation tests to
tests/unit/type-check-except/ - Tests using raw values to verify Pydantic validation now excluded from type checking
- Original tests fixed to use properly wrapped attribute types
- Clean separation: type-safe tests vs validation behavior tests
- Moved files:
test_pydantic.py,test_basic.py,test_update_api.py,test_cardinality.py,test_list_default.py
Benefits¶
- Clearer code: Keyword arguments make field names explicit at call sites
- Better IDE support: Explicit
= Noneimproves autocomplete for optional fields - 100% type safety: Pyright validates correctly with zero false positives
- Maintainability: Adding new fields doesn't break existing constructor calls
- Error prevention: Type checker catches argument order mistakes at development time
๐ Documentation¶
Automatic Conversions Documented¶
avg()โmeanin TypeQL- TypeDB 3.x uses
meaninstead ofavg - User calls
Age.avg(), generatesmean($age)in TypeQL - Result key converted back to
avg_agefor consistency - Clearly documented in docstrings and implementation comments
regex()โlikein TypeQL- TypeQL uses
likefor regex pattern matching regex()provided as user-friendly alias- Both methods generate identical TypeQL output
- Documented in method docstrings and code comments
TypeQL Compliance Verification¶
- All expressions verified against TypeDB 3.x specification
- Comparison operators:
>,<,>=,<=,==,!=โ - String operations:
contains,likeโ - Aggregations:
sum,mean,max,min,median,std,countโ - Boolean logic:
;(AND),or,notโ - Created
tmp/typeql_verification.mdandtmp/automatic_conversions.md
Examples Updated¶
- Updated query_expressions.py to use new API
- All field-based expressions converted to attribute type-based
- Added notes about API improvements and type safety
- Location:
examples/advanced/query_expressions.py
๐งช Testing¶
Test Results¶
- 417/417 tests passing (100% pass rate) โ
- Unit tests: 284/284 passing (0.3s)
- Integration tests: 133/133 passing
- Type checking: 0 errors, 0 warnings, 0 informations โ
- All type errors eliminated (250 errors โ 0 errors)
Tests Updated¶
- Updated field reference tests for new API
- Tests now check
attr_typeinstead offieldattributes - All expression creation and TypeQL generation tests passing
- Location:
tests/unit/expressions/test_field_refs.py
Test Organization¶
- Integration tests reorganized into subdirectories
tests/integration/queries/test_expressions.py- Query expression integration teststests/integration/crud/relations/test_abstract_roles.py- Abstract role type tests- Better organization: crud/, queries/, schema/ subdirectories
- Improved test discoverability and maintenance
๐ง Type Safety¶
Type Checking Improvements¶
- Eliminated all expression-related type errors
- Before: 26 errors (
.gt(),.avg()"not a known attribute" errors) - After: 0 errors โ
- Type checkers now fully understand class method API
- Pyright passes with 0 errors, 0 warnings, 0 informations
Benefits¶
- Type-safe: Full type checker support with zero errors
- Concise: Shorter syntax (
Age.gt()vsPerson.age.gt()) - Validated: Runtime checks prevent invalid queries
- Compatible: Old API still works for gradual migration
- Documented: All automatic conversions clearly explained
๐ฆ Key Files Modified¶
type_bridge/attribute/base.py- Added class methods for comparisons and aggregationstype_bridge/attribute/string.py- Added string-specific class methodstype_bridge/expressions/comparison.py- Changed toattr_type-basedtype_bridge/expressions/string.py- Changed toattr_type-basedtype_bridge/expressions/aggregate.py- Changed toattr_type-basedtype_bridge/expressions/base.py- Addedget_attribute_types()methodtype_bridge/expressions/boolean.py- Added recursive attribute type collectiontype_bridge/fields.py- Updated to delegate to attribute class methodstype_bridge/crud.py- Added validation in filter() methodsexamples/advanced/query_expressions.py- Updated to use new API
[0.4.4] - 2025-11-19¶
๐ Bug Fixes¶
- Fixed inherited attributes not included in insert/get operations
- Entity and Relation insert queries now include all inherited attributes
- Fetch operations properly extract inherited attribute values
- Added
get_all_attributes()method to collect attributes from entire class hierarchy - Location:
type_bridge/models/base.py,type_bridge/models/entity.py,type_bridge/crud.py
๐ API Changes¶
- Removed deprecated
EntityFlagsandRelationFlagsaliases - Use
TypeFlagsfor both entities and relations - All example files updated to use
TypeFlags - Documentation updated to reflect unified API
๐ Documentation¶
- Updated CLAUDE.md: Replaced all EntityFlags/RelationFlags references with TypeFlags
- Updated examples: All 17 example files now use the unified TypeFlags API
[0.4.0] - 2025-11-15¶
๐ New Features¶
Docker Integration for Testing¶
- Automated Docker management for integration tests
- Added
docker-compose.ymlwith TypeDB 3.5.5 server configuration - Created
test-integration.shscript for automated Docker lifecycle management - Docker containers start/stop automatically with test fixtures
- Location:
docker-compose.yml,test-integration.sh,tests/integration/conftest.py - Optional Docker usage: Set
USE_DOCKER=falseto use existing TypeDB server - Port configuration: TypeDB server on port 1729
Schema Validation¶
- Duplicate attribute type detection
- Prevents using the same attribute type for multiple fields in an entity/relation
- Validates during schema generation to catch design errors early
- Raises
SchemaValidationErrorwith detailed field information - Location:
type_bridge/schema/info.py,type_bridge/schema/exceptions.py - Why it matters: TypeDB stores ownership by attribute type, not by field name
- Using
created: TimeStampandmodified: TimeStampcreates a single ownership - This causes cardinality constraint violations at runtime
- Solution: Use distinct types like
CreatedStampandModifiedStamp
๐งช Testing¶
Test Infrastructure¶
- Improved test organization: 347 total tests (249 unit + 98 integration)
- Docker-based integration tests: Automatic container lifecycle management
- Added duplicate attribute validation tests: 6 new tests for schema validation
- Location:
tests/unit/validation/test_duplicate_attributes.py
๐ Documentation¶
- Updated CLAUDE.md:
- Added Docker setup instructions for integration tests
- Documented duplicate attribute type validation rules
- Added schema validation best practices
- Included examples of correct vs incorrect attribute usage
- Updated test execution patterns: Docker vs manual TypeDB server options
๐ง CI/CD¶
- Updated GitHub Actions workflow:
- Integrated Docker Compose for automated integration testing
- Added TypeDB 3.5.5 service container configuration
- Location:
.github/workflows/(multiple CI updates)
๐ฆ Dependencies¶
- Added
docker-composesupport for development workflow - No changes to runtime dependencies
๐ Bug Fixes¶
- Fixed test fixture ordering: Improved integration test reliability with Docker
- Enhanced error messages: Schema validation errors now include field names
[0.3.X] - 2025-01-14¶
โ Full TypeDB 3.x Compatibility¶
Major Achievement: 100% Test Pass Rate (341/341 tests)
Fixed¶
Query Pagination¶
- Fixed TypeQL clause ordering: offset must come BEFORE limit in TypeDB 3.x
- Changed
limit X; offset Y;โoffset Y; limit X; - Location:
type_bridge/query.py:151-154 - Added automatic sorting for pagination: TypeDB 3.x requires sorting for reliable offset results
- Automatically finds and sorts by key attributes when using limit/offset
- Falls back to required attributes if no key exists
- Location:
type_bridge/crud.py:447-468
Schema Conflict Detection¶
- Updated to TypeDB 3.x syntax: Changed from
subtoisafor type queries - TypeDB 3.x uses
$e isa personinstead of$e sub entity - Fixed
has_existing_schema()to properly detect existing types - Fixed
_type_exists()to use correct TypeQL syntax - Location:
type_bridge/schema/manager.py:65-284 - Improved conflict detection: Now properly raises SchemaConflictError when types exist
Type Safety¶
- Fixed AttributeFlags attribute access: Changed
cardinality_mintocard_min - Resolved pyright type checking error
- Location:
type_bridge/crud.py:460
Testing¶
Test Results¶
- Unit tests: 243/243 passing (100%) - ~0.3s runtime
- Integration tests: 98/98 passing (100%) - ~18s runtime
- Total: 341/341 passing (100%)
Test Coverage¶
- All 9 TypeDB attribute types fully tested (Boolean, Date, DateTime, DateTimeTZ, Decimal, Double, Duration, Integer, String)
- Full CRUD operations for each type (insert, fetch, update, delete)
- Multi-value attribute operations
- Query pagination with limit/offset/sort
- Schema conflict detection and inheritance
- Reserved word validation
Code Quality¶
- โ Ruff linting: 0 errors, 0 warnings
- โ Ruff formatting: All 112 files properly formatted
- โ Pyright type checking: 0 errors, 0 warnings, 0 informations
Documentation¶
- Updated README.md with current test counts and features
- Updated CLAUDE.md testing strategy section
- Added TypeDB 3.x compatibility notes
- Documented pagination requirements and automatic sorting
Key Files Modified¶
type_bridge/query.py- Fixed clause ordering in build()type_bridge/crud.py- Added automatic sorting for pagination, fixed attribute accesstype_bridge/schema/manager.py- Updated to TypeDB 3.xisasyntax
[0.2.0] - Previous Release¶
See git history for earlier changes.