Skip to content

Commit cf473ce

Browse files
committed
Update labels api and keywords
1 parent c397a29 commit cf473ce

File tree

3 files changed

+329
-18
lines changed

3 files changed

+329
-18
lines changed

README.md

Lines changed: 289 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,8 @@ Records can be manipulated within transactions for atomic operations:
10171017

10181018
```python
10191019
# Start a transaction
1020-
with db.transactions.begin() as transaction:
1020+
transaction = db.transactions.begin()
1021+
try:
10211022
# Create user
10221023
user = db.records.create(
10231024
"USER",
@@ -1044,8 +1045,24 @@ with db.transactions.begin() as transaction:
10441045
transaction=transaction
10451046
)
10461047

1047-
# Transaction will automatically commit if no errors occur
1048-
# If an error occurs, it will automatically rollback
1048+
# Explicitly commit the transaction to make changes permanent
1049+
transaction.commit()
1050+
except Exception as e:
1051+
# Rollback if any error occurs
1052+
transaction.rollback()
1053+
raise e
1054+
1055+
# Alternative: Using context manager
1056+
with db.transactions.begin() as transaction:
1057+
# Perform operations...
1058+
user = db.records.create(
1059+
"USER",
1060+
{"name": "John Doe"},
1061+
transaction=transaction
1062+
)
1063+
1064+
# Must explicitly commit - transactions are NOT automatically committed
1065+
transaction.commit()
10491066
```
10501067

10511068
---
@@ -1280,8 +1297,9 @@ property_with_value = {
12801297
Properties API methods support optional transactions for atomic operations:
12811298

12821299
```python
1283-
# Using a transaction
1284-
with db.transactions.begin() as transaction:
1300+
# Using a transaction with explicit commit
1301+
transaction = db.transactions.begin()
1302+
try:
12851303
# Perform multiple property-related operations
12861304
property_to_delete = db.properties.find(
12871305
{"where": {"name": "temp_property"}},
@@ -1292,7 +1310,29 @@ with db.transactions.begin() as transaction:
12921310
property_id=property_to_delete['id'],
12931311
transaction=transaction
12941312
)
1295-
# Transaction will automatically commit if no errors occur
1313+
1314+
# Explicitly commit the transaction
1315+
transaction.commit()
1316+
except Exception as e:
1317+
# Rollback if any error occurs
1318+
transaction.rollback()
1319+
raise e
1320+
1321+
# Alternative: Using context manager (auto-rollback on error)
1322+
with db.transactions.begin() as transaction:
1323+
# Perform operations
1324+
property_to_delete = db.properties.find(
1325+
{"where": {"name": "temp_property"}},
1326+
transaction=transaction
1327+
)[0]
1328+
1329+
db.properties.delete(
1330+
property_id=property_to_delete['id'],
1331+
transaction=transaction
1332+
)
1333+
1334+
# Must explicitly commit - transactions are NOT automatically committed
1335+
transaction.commit()
12961336
```
12971337

12981338
## Error Handling
@@ -1307,3 +1347,246 @@ except RushDBError as e:
13071347
print(f"Error: {e}")
13081348
print(f"Error Details: {e.details}")
13091349
```
1350+
1351+
---
1352+
1353+
# LabelsAPI Documentation
1354+
1355+
The `LabelsAPI` class provides methods for discovering and working with record labels in RushDB. Labels are used to categorize and type records, similar to table names in relational databases.
1356+
1357+
## Class Definition
1358+
1359+
```python
1360+
class LabelsAPI(BaseAPI):
1361+
```
1362+
1363+
## Methods
1364+
1365+
### find()
1366+
1367+
Discovers labels (record types) that exist in the database and can optionally filter them based on search criteria.
1368+
1369+
**Signature:**
1370+
1371+
```python
1372+
def find(
1373+
self,
1374+
search_query: Optional[SearchQuery] = None,
1375+
transaction: Optional[Transaction] = None
1376+
) -> Dict[str, int]
1377+
```
1378+
1379+
**Arguments:**
1380+
1381+
- `search_query` (Optional[SearchQuery]): Search criteria to filter labels
1382+
- `transaction` (Optional[Transaction]): Optional transaction object
1383+
1384+
**Returns:**
1385+
1386+
- `Dict[str, int]`: Dictionary mapping label names to their record counts
1387+
1388+
**Example:**
1389+
1390+
```python
1391+
# Get all labels in the database
1392+
all_labels = db.labels.find()
1393+
print("Available labels:", all_labels)
1394+
# Output: {'USER': 150, 'DEPARTMENT': 12, 'PROJECT': 45, 'COMPANY': 3}
1395+
1396+
# Search for labels amongst records matching a pattern
1397+
from rushdb.models.search_query import SearchQuery
1398+
query = SearchQuery(where={"name": {"$contains": "alice"}})
1399+
user_labels = db.labels.find(query)
1400+
print("Labels for records containing 'alice':", user_labels)
1401+
# Output: {'USER': 2, 'EMPLOYEE': 1}
1402+
```
1403+
1404+
## Complete Usage Example
1405+
1406+
```python
1407+
# Discover all record types in the database
1408+
all_labels = db.labels.find()
1409+
print(f"Database contains {len(all_labels)} record types:")
1410+
for label, count in all_labels.items():
1411+
print(f" - {label}: {count} records")
1412+
1413+
# Find labels for records with specific criteria
1414+
query = SearchQuery(where={
1415+
"status": "active",
1416+
"created_date": {"$gte": "2023-01-01"}
1417+
})
1418+
active_labels = db.labels.find(query)
1419+
print("Labels for active records:")
1420+
for label, count in active_labels.items():
1421+
print(f" - {label}: {count} active records")
1422+
1423+
# Use with transaction
1424+
transaction = db.transactions.begin()
1425+
try:
1426+
labels_in_tx = db.labels.find(transaction=transaction)
1427+
# Process labels...
1428+
transaction.commit()
1429+
except Exception as e:
1430+
transaction.rollback()
1431+
raise e
1432+
```
1433+
1434+
---
1435+
1436+
# RelationshipsAPI Documentation
1437+
1438+
The `RelationshipsAPI` class provides functionality for querying and analyzing relationships between records in RushDB. Relationships represent connections or associations between different records.
1439+
1440+
## Class Definition
1441+
1442+
```python
1443+
class RelationshipsAPI(BaseAPI):
1444+
```
1445+
1446+
## Methods
1447+
1448+
### find()
1449+
1450+
Search for and retrieve relationships matching the specified criteria with support for pagination and transactions.
1451+
1452+
**Signature:**
1453+
1454+
```python
1455+
async def find(
1456+
self,
1457+
search_query: Optional[SearchQuery] = None,
1458+
pagination: Optional[PaginationParams] = None,
1459+
transaction: Optional[Union[Transaction, str]] = None
1460+
) -> List[Relationship]
1461+
```
1462+
1463+
**Arguments:**
1464+
1465+
- `search_query` (Optional[SearchQuery]): Search criteria to filter relationships
1466+
- `pagination` (Optional[PaginationParams]): Pagination options with `limit` and `skip`
1467+
- `transaction` (Optional[Union[Transaction, str]]): Optional transaction object or ID
1468+
1469+
**Returns:**
1470+
1471+
- `List[Relationship]`: List of relationships matching the search criteria
1472+
1473+
**Example:**
1474+
1475+
```python
1476+
import asyncio
1477+
from rushdb.models.search_query import SearchQuery
1478+
1479+
async def main():
1480+
# Find all relationships
1481+
all_relationships = await db.relationships.find()
1482+
print(f"Total relationships: {len(all_relationships)}")
1483+
1484+
# Find relationships with pagination
1485+
pagination = {"limit": 50, "skip": 0}
1486+
first_page = await db.relationships.find(pagination=pagination)
1487+
1488+
# Find specific relationship types
1489+
query = SearchQuery(where={"type": "BELONGS_TO"})
1490+
belongs_to_rels = await db.relationships.find(search_query=query)
1491+
1492+
# Find relationships involving specific records
1493+
user_query = SearchQuery(where={
1494+
"$or": [
1495+
{"source_id": "user-123"},
1496+
{"target_id": "user-123"}
1497+
]
1498+
})
1499+
user_relationships = await db.relationships.find(search_query=user_query)
1500+
1501+
# Run the async function
1502+
asyncio.run(main())
1503+
```
1504+
1505+
## PaginationParams
1506+
1507+
The `PaginationParams` TypedDict defines pagination options:
1508+
1509+
```python
1510+
class PaginationParams(TypedDict, total=False):
1511+
limit: int # Maximum number of relationships to return
1512+
skip: int # Number of relationships to skip
1513+
```
1514+
1515+
## Complete Usage Example
1516+
1517+
```python
1518+
import asyncio
1519+
from rushdb.models.search_query import SearchQuery
1520+
1521+
async def explore_relationships():
1522+
# Get overview of all relationships
1523+
all_rels = await db.relationships.find()
1524+
print(f"Database contains {len(all_rels)} relationships")
1525+
1526+
# Paginate through relationships
1527+
page_size = 25
1528+
page = 0
1529+
1530+
while True:
1531+
pagination = {"limit": page_size, "skip": page * page_size}
1532+
relationships = await db.relationships.find(pagination=pagination)
1533+
1534+
if not relationships:
1535+
break
1536+
1537+
print(f"Page {page + 1}: {len(relationships)} relationships")
1538+
for rel in relationships:
1539+
print(f" {rel['source_id']} --[{rel['type']}]--> {rel['target_id']}")
1540+
1541+
page += 1
1542+
if len(relationships) < page_size:
1543+
break
1544+
1545+
# Find relationships by type
1546+
query = SearchQuery(where={"type": "WORKS_ON"})
1547+
work_relationships = await db.relationships.find(search_query=query)
1548+
print(f"Found {len(work_relationships)} 'WORKS_ON' relationships")
1549+
1550+
# Find relationships within a transaction
1551+
transaction = db.transactions.begin()
1552+
try:
1553+
tx_rels = await db.relationships.find(transaction=transaction)
1554+
# Process relationships...
1555+
transaction.commit()
1556+
except Exception as e:
1557+
transaction.rollback()
1558+
raise e
1559+
1560+
# Run the example
1561+
asyncio.run(explore_relationships())
1562+
```
1563+
1564+
## Working with Transactions
1565+
1566+
Both LabelsAPI and RelationshipsAPI support transactions:
1567+
1568+
```python
1569+
import asyncio
1570+
1571+
async def transaction_example():
1572+
transaction = db.transactions.begin()
1573+
try:
1574+
# Find labels within transaction
1575+
labels = db.labels.find(transaction=transaction)
1576+
1577+
# Find relationships within transaction
1578+
relationships = await db.relationships.find(transaction=transaction)
1579+
1580+
# Perform operations based on discovered data...
1581+
1582+
# Explicitly commit the transaction
1583+
transaction.commit()
1584+
except Exception as e:
1585+
# Rollback on any error
1586+
transaction.rollback()
1587+
raise e
1588+
1589+
asyncio.run(transaction_example())
1590+
```
1591+
1592+
**Note:** The RelationshipsAPI methods are async and require the use of `await` and `asyncio` for proper execution.

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy