Data - SQL Database
Managed PostgreSQL databases with full SQL support, transactions, and automatic backups for relational data storage.
Overview
Data provides managed PostgreSQL databases optimized for AI applications:
- Full SQL support with transactions
- Automatic daily backups
- Connection pooling
- Schema management
- Batch query execution
Quick Start
import { Tenzro } from 'tenzro';const tenzro = new Tenzro({ apiKey: 'your-api-key' });// Create a SQL databaseconst db = await tenzro.data.create({projectId: 'project-id',db_name: 'my-app-db',maxConnections: 20,});// Create a tableawait tenzro.data.createTable(db.data_db_id, 'users', [{ name: 'id', type: 'SERIAL', primaryKey: true },{ name: 'email', type: 'VARCHAR(255)', unique: true },{ name: 'name', type: 'VARCHAR(255)' },{ name: 'created_at', type: 'TIMESTAMP', default: 'NOW()' },]);// Insert dataawait tenzro.data.query(db.data_db_id,'INSERT INTO users (email, name) VALUES ($1, $2)',['john@example.com', 'John Doe']);// Query dataconst { rows } = await tenzro.data.query(db.data_db_id,'SELECT * FROM users WHERE email = $1',['john@example.com']);console.log(rows[0]); // { id: 1, email: 'john@example.com', ... }
SDK Reference
Database Management
Create Database
const db = await tenzro.data.create({projectId: string, // Requireddb_name: string, // Requireddescription?: string, // OptionalmaxConnections?: number, // Default: 20});
List Databases
const { data, count } = await tenzro.data.list(projectId);
Get Statistics
const stats = await tenzro.data.getStats(dataDbId);// Returns: { tableCount, totalRows, diskUsage, connectionCount }
Query Execution
Execute Query
const result = await tenzro.data.query(dataDbId,sql: string, // SQL queryparams?: unknown[], // Parameterized valuestransaction?: boolean // Run in transaction);// Result type:interface QueryResult {rows: any[];rowCount: number;fields: { name: string; type: string }[];}
Batch Queries
const results = await tenzro.data.batch(dataDbId, [{ sql: 'INSERT INTO orders (user_id) VALUES ($1)', params: [1] },{ sql: 'UPDATE users SET order_count = order_count + 1 WHERE id = $1', params: [1] },{ sql: 'SELECT * FROM orders WHERE user_id = $1', params: [1] },]);// Returns: QueryResult[] - one result per query
Table Operations
Create Table
await tenzro.data.createTable(dataDbId, 'products', [{ name: 'id', type: 'SERIAL', primaryKey: true },{ name: 'name', type: 'VARCHAR(255)', nullable: false },{ name: 'price', type: 'DECIMAL(10,2)', nullable: false },{ name: 'category_id', type: 'INTEGER', references: { table: 'categories', column: 'id' } },{ name: 'created_at', type: 'TIMESTAMP', default: 'NOW()' },]);
List Tables
const { tables, count } = await tenzro.data.listTables(dataDbId);// tables: string[] - table names
Get Table Info
const info = await tenzro.data.getTableInfo(dataDbId, 'users');// Returns: { name, columns: [...], rowCount }
Drop Table
await tenzro.data.dropTable(dataDbId, 'old_table');
Column Types
| Type | Description | Example |
|---|---|---|
SERIAL | Auto-incrementing integer | Primary keys |
INTEGER | 32-bit integer | Counts, IDs |
BIGINT | 64-bit integer | Large numbers |
DECIMAL(p,s) | Exact decimal | Money, prices |
VARCHAR(n) | Variable string | Names, emails |
TEXT | Unlimited string | Descriptions |
BOOLEAN | True/false | Flags |
TIMESTAMP | Date and time | Created/updated |
JSONB | Binary JSON | Flexible data |
UUID | Unique identifier | External IDs |
Transactions
Execute multiple queries atomically:
// Using batch with implicit transactionconst results = await tenzro.data.batch(dataDbId, [{ sql: 'BEGIN' },{ sql: 'INSERT INTO orders (user_id, total) VALUES ($1, $2)', params: [1, 99.99] },{ sql: 'UPDATE inventory SET quantity = quantity - 1 WHERE product_id = $1', params: [1] },{ sql: 'COMMIT' },]);// Or using single query with transaction flagawait tenzro.data.query(dataDbId, `INSERT INTO orders (user_id, total) VALUES ($1, $2);UPDATE inventory SET quantity = quantity - 1 WHERE product_id = $3;`, [1, 99.99, 1], true);
Examples
User Management
// Create users tableawait tenzro.data.createTable(dataDbId, 'users', [{ name: 'id', type: 'UUID', primaryKey: true, default: 'gen_random_uuid()' },{ name: 'email', type: 'VARCHAR(255)', unique: true, nullable: false },{ name: 'password_hash', type: 'VARCHAR(255)', nullable: false },{ name: 'name', type: 'VARCHAR(255)' },{ name: 'metadata', type: 'JSONB', default: "'{}'" },{ name: 'created_at', type: 'TIMESTAMP', default: 'NOW()' },{ name: 'updated_at', type: 'TIMESTAMP', default: 'NOW()' },]);// Register userasync function registerUser(email: string, passwordHash: string, name: string) {const { rows } = await tenzro.data.query(dataDbId, `INSERT INTO users (email, password_hash, name)VALUES ($1, $2, $3)RETURNING id, email, name, created_at`, [email, passwordHash, name]);return rows[0];}// Find user by emailasync function findUserByEmail(email: string) {const { rows } = await tenzro.data.query(dataDbId, `SELECT * FROM users WHERE email = $1`, [email]);return rows[0] || null;}
Agent Memory Storage
// Create conversation tableawait tenzro.data.createTable(dataDbId, 'conversations', [{ name: 'id', type: 'UUID', primaryKey: true, default: 'gen_random_uuid()' },{ name: 'agent_id', type: 'VARCHAR(255)', nullable: false },{ name: 'user_id', type: 'VARCHAR(255)', nullable: false },{ name: 'created_at', type: 'TIMESTAMP', default: 'NOW()' },]);await tenzro.data.createTable(dataDbId, 'messages', [{ name: 'id', type: 'UUID', primaryKey: true, default: 'gen_random_uuid()' },{ name: 'conversation_id', type: 'UUID', references: { table: 'conversations', column: 'id' } },{ name: 'role', type: 'VARCHAR(20)', nullable: false },{ name: 'content', type: 'TEXT', nullable: false },{ name: 'metadata', type: 'JSONB', default: "'{}'" },{ name: 'created_at', type: 'TIMESTAMP', default: 'NOW()' },]);// Get conversation historyasync function getConversationHistory(conversationId: string, limit = 50) {const { rows } = await tenzro.data.query(dataDbId, `SELECT role, content, metadata, created_atFROM messagesWHERE conversation_id = $1ORDER BY created_at DESCLIMIT $2`, [conversationId, limit]);return rows.reverse();}
Best Practices
- Use parameterized queries: Always use
$1, $2placeholders to prevent SQL injection - Index frequently queried columns: Create indexes for columns in WHERE clauses
- Use JSONB for flexible data: Store variable metadata in JSONB columns
- Connection pooling: Set appropriate
maxConnectionsfor your workload - Batch operations: Use batch queries for multiple related operations
Limits
| Resource | Limit |
|---|---|
| Max connections per database | 100 |
| Max query result size | 100 MB |
| Max queries per batch | 100 |
| Query timeout | 30 seconds |
| Max database size | 100 GB |