A high-performance PostgreSQL database backend for Gramps genealogy software that provides advanced database capabilities and superior performance for genealogical data management while maintaining full compatibility with the Gramps data model.
Project Status: Experimental - Rigorous testing completed | GitHub Repository | Submit Issues
The PostgreSQL Enhanced addon provides a professional-grade database backend for Gramps with capabilities far exceeding both the standard SQLite backend and the original PostgreSQL addon. It has been rigorously tested with databases containing over 100,000 persons while maintaining excellent performance, even over network connections.
- Modern psycopg3 - Uses the latest PostgreSQL adapter (psycopg 3.1+, not psycopg2)
- Dual Storage Format - Maintains both pickle blobs (for Gramps compatibility) and JSONB (for advanced queries)
- Two Database Modes - Both fully tested and working:
- Monolithic Mode - All family trees in one database with table prefixes
- Separate Mode - Each family tree gets its own PostgreSQL database
- Full Gramps Compatibility - Works with all existing Gramps tools and reports
- Transaction Safety - Proper savepoint handling and rollback capabilities
- Data Preservation - Intelligent design that preserves data when trees are removed from Gramps
- 3-10x faster for most operations
- 12x faster person lookups (6,135/sec vs 500/sec)
- 100x faster name searches using indexes instead of full scans
- Network accessible - Multiple users can work with the same database
- True concurrent access - No database locking issues
- Handles 100,000+ persons effortlessly where SQLite struggles
- Modern psycopg3 instead of deprecated psycopg2
- JSONB storage enables advanced queries impossible with blob-only storage
- Connection pooling for better resource management
- Recursive CTEs for relationship path finding
- Full-text search capabilities with proper indexing
- Better NULL handling - Fixes issues in original implementation
- Table prefix support - Allows multiple trees in one database
- Relationship path finding - Find connections between any two people
- Common ancestor detection - Identify shared ancestors efficiently
- Full-text search - Search across all text fields with PostgreSQL's powerful text search
- Duplicate detection - Find potential duplicate persons using fuzzy matching
- Complex filters - Use SQL directly for sophisticated queries
- Statistical analysis - Aggregate queries across entire database
- Tested with: 100,000+ person databases
- Import rate: ~13 persons/second for large GEDCOM files
- Network performance: Remains performant even over network connections
- Large import test: 86,647 persons imported successfully (2.9GB database)
- Memory efficiency: Peak 473MB for 86k person import
- Query performance: Millisecond response times for complex queries
- pg_trgm - Fuzzy text matching and similarity searches
- btree_gin - Advanced JSONB indexing for faster queries
- intarray - Efficient array operations
- pgvector - Vector similarity search capabilities
- Apache AGE - Graph database features for relationship analysis
- PostGIS - Geospatial queries for location-based research
- Gramps: Version 5.1 or higher (tested with 5.2.3 and 6.0.3)
- PostgreSQL: Version 15 or higher
- Python: 3.8 or higher (as required by your Gramps version)
- psycopg: Version 3.1 or higher (NOT psycopg2!)
-- Core extensions for enhanced functionality
CREATE EXTENSION IF NOT EXISTS "uuid-ossp"; -- UUID generation
CREATE EXTENSION IF NOT EXISTS "btree_gin"; -- Improved JSONB indexing
CREATE EXTENSION IF NOT EXISTS "pg_trgm"; -- Fuzzy text matching
CREATE EXTENSION IF NOT EXISTS "intarray"; -- Array operations
-- Optional advanced extensions
CREATE EXTENSION IF NOT EXISTS "pgvector"; -- Vector similarity search
CREATE EXTENSION IF NOT EXISTS "age"; -- Graph database features
CREATE EXTENSION IF NOT EXISTS "postgis"; -- Geospatial capabilitiesUbuntu/Debian:
sudo apt update
sudo apt install postgresql-15 postgresql-contrib-15macOS:
brew install postgresql@15
brew services start postgresql@15Windows: Download and install from postgresql.org
# Install psycopg3 with binary support
pip install 'psycopg[binary]>=3.1'# Create a database user for Gramps
sudo -u postgres createuser -P genealogy_user
# Grant database creation privilege (required for separate mode)
sudo -u postgres psql -c "ALTER USER genealogy_user CREATEDB;"
# Create template database with extensions (optional but recommended)
sudo -u postgres psql <<EOF
CREATE DATABASE template_gramps TEMPLATE template0;
\c template_gramps
CREATE EXTENSION IF NOT EXISTS "uuid-ossp";
CREATE EXTENSION IF NOT EXISTS "pg_trgm";
CREATE EXTENSION IF NOT EXISTS "btree_gin";
GRANT ALL ON DATABASE template_gramps TO genealogy_user;
UPDATE pg_database SET datistemplate = true WHERE datname = 'template_gramps';
EOFOption A: Download from GitHub
# Create plugins directory if it doesn't exist
mkdir -p ~/.local/share/gramps/gramps60/plugins/
# Clone the repository
cd ~/.local/share/gramps/gramps60/plugins/
git clone https://github.com/glamberson/gramps-postgresql-enhanced.git PostgreSQLEnhancedOption B: Manual Installation
- Download the addon files
- Place them in:
~/.local/share/gramps/gramps60/plugins/PostgreSQLEnhanced/ - Ensure all Python files are present
The PostgreSQL Enhanced addon uses a file-based configuration system. Note: The GUI fields for host/username/password in Gramps are currently not utilized - configuration is managed through the connection_info.txt file for consistency and reliability.
The addon looks for connection_info.txt in this priority order:
-
Central Plugin Configuration (used by both modes):
~/.local/share/gramps/gramps60/plugins/PostgreSQLEnhanced/connection_info.txt -
Per-Tree Configuration (future enhancement):
~/.local/share/gramps/grampsdb/<tree_id>/connection_info.txt
Create or edit connection_info.txt with the following format:
# PostgreSQL Enhanced Connection Configuration
# This file controls how the addon connects to PostgreSQL
# Connection details
host = 192.168.10.90 # PostgreSQL server address
port = 5432 # PostgreSQL port
user = genealogy_user # Database username
password = YourPassword # Database password
# Database mode: 'separate' or 'monolithic'
database_mode = monolithic
# For monolithic mode only: name of the shared database
shared_database_name = gramps_monolithic
# Optional settings (uncomment to use)
# pool_size = 10 # Connection pool size
# sslmode = prefer # SSL connection mode
# connect_timeout = 10 # Connection timeout in seconds- How it works: All family trees share one PostgreSQL database
- Table naming: Each tree's tables are prefixed with
tree_<treeid>_ - Example: Tree "68932301" creates tables like
tree_68932301_person - Configuration: Uses central
connection_info.txtin plugin directory - Advantages:
- Single database to manage and backup
- Can query across multiple trees
- Works without CREATEDB privilege
- Simplified administration
- Best for: Organizations managing multiple related trees
- How it works: Each family tree gets its own PostgreSQL database
- Database naming: Creates database named after the tree ID
- Table naming: Direct names without prefixes
- Configuration: Uses central
connection_info.txtin plugin directory - Advantages:
- Complete isolation between trees
- Simpler table structure
- Per-tree backup/restore
- Better for multi-user scenarios
- Independent database tuning per tree
- Best for: Large independent trees or multi-tenant environments
Before creating a tree, ensure your connection_info.txt is properly configured:
# Edit the configuration file
nano ~/.local/share/gramps/gramps60/plugins/PostgreSQLEnhanced/connection_info.txt- Open Gramps
- Go to Family Trees → Manage Family Trees
- Click New
- Enter a name for your tree
- For Database backend, select "PostgreSQL Enhanced"
- Click Load Family Tree
When you create a new tree:
- Gramps generates a unique tree ID (8-character hex string like "68932301")
- Creates registration directory:
~/.local/share/gramps/grampsdb/<tree_id>/ - Writes metadata files:
database.txtcontaining "postgresqlenhanced"name.txtcontaining your chosen tree name
- Addon reads configuration from central
connection_info.txt - In monolithic mode: Creates tables with prefix
tree_<tree_id>_in shared database - In separate mode: Creates new database named after tree ID
If you have tables in PostgreSQL that Gramps doesn't know about, you can register them:
# Use the provided registration script
./register_existing_tree.sh <tree_id> "<tree_name>"
# Or manually:
TREE_ID="68932301"
TREE_NAME="Smith Family"
mkdir -p ~/.local/share/gramps/grampsdb/${TREE_ID}
echo "postgresqlenhanced" > ~/.local/share/gramps/grampsdb/${TREE_ID}/database.txt
echo "${TREE_NAME}" > ~/.local/share/gramps/grampsdb/${TREE_ID}/name.txtAfter registration, restart Gramps and the tree will appear in the Family Tree Manager.
To switch from monolithic to separate mode (or vice versa):
- Export your tree as GEDCOM or Gramps XML
- Edit
connection_info.txtto changedatabase_mode - Create a new tree in Gramps
- Import your exported data
When you delete a tree from Gramps, the PostgreSQL tables/database are intentionally preserved. This is a critical safety feature that:
- Prevents accidental data loss of irreplaceable genealogical data
- Allows recovery of "deleted" trees
- Provides an audit trail
- Requires explicit administrative action for permanent deletion
This is especially important when managing genealogical data representing centuries of family history.
For Monolithic Mode (removing tables):
# Remove tables for a specific tree
TREE_ID="689304d4" # Replace with actual tree ID
# Drop all tables for that tree
for table in person family event place source citation repository media note tag; do
PGPASSWORD='YourPassword' psql -h localhost -U genealogy_user -d gramps_monolithic \
-c "DROP TABLE IF EXISTS tree_${TREE_ID}_${table} CASCADE;"
doneFor Separate Mode (removing database):
# Drop entire database for a tree
TREE_ID="689304d4"
PGPASSWORD='YourPassword' psql -h localhost -U genealogy_user -d postgres \
-c "DROP DATABASE IF EXISTS ${TREE_ID};"# Find common ancestors between two people
ancestors = db.find_common_ancestors(person1_handle, person2_handle)
# Find relationship path
path = db.find_relationship_path(person1_handle, person2_handle)# Search across all text fields
results = db.search_all_text("immigration 1850")# Find potential duplicate persons (requires pg_trgm)
duplicates = db.enhanced_queries.find_potential_duplicates(threshold=0.8)For power users, direct SQL queries are possible:
-- Find all persons born in a specific year
SELECT json_data->>'gramps_id' as id,
json_data->'primary_name'->>'first_name' as given,
json_data->'primary_name'->'surname_list'->0->>'surname' as surname
FROM tree_68932301_person
WHERE json_data->'birth_ref_index'->>'year' = '1850';Edit postgresql.conf for optimal performance:
# Memory settings (adjust based on available RAM)
shared_buffers = 256MB
effective_cache_size = 2GB
work_mem = 16MB
maintenance_work_mem = 512MB
# For SSD storage
random_page_cost = 1.1
effective_io_concurrency = 200
# Connection pooling
max_connections = 100Enable connection pooling in connection_info.txt:
pool_size = 10# Set environment variable before starting Gramps
export GRAMPS_POSTGRESQL_DEBUG=1
gramps
# Check debug log
tail -f ~/.gramps/postgresql_enhanced_debug.log"psycopg not found"
- Ensure you installed psycopg3, not psycopg2:
pip install 'psycopg[binary]'
"Connection refused"
- Check PostgreSQL is running:
sudo systemctl status postgresql - Verify connection details in
connection_info.txt - Check PostgreSQL authentication in
pg_hba.conf
"Insufficient privilege"
- For separate mode, user needs CREATEDB privilege:
ALTER USER genealogy_user CREATEDB;
Tables not found
- Check you're using the correct database mode in configuration
- Verify table prefix matches tree ID in monolithic mode
- ✅ Both database modes thoroughly tested
- ✅ Successfully tested with 100,000+ person databases
- ✅ Network performance verified
- ✅ Import/export functionality validated
- ✅ All Gramps tools compatibility confirmed
- ✅ Transaction integrity verified
- ✅ Concurrent access tested
# Test database connection
PGPASSWORD='YourPassword' psql -h localhost -U genealogy_user -d gramps_monolithic -c "SELECT version();"
# Check if tables exist (monolithic mode)
PGPASSWORD='YourPassword' psql -h localhost -U genealogy_user -d gramps_monolithic -c "\dt tree_*"
# Run addon verification
cd ~/.local/share/gramps/gramps60/plugins/PostgreSQLEnhanced
python3 verify_addon.py# Check database statistics
PGPASSWORD='YourPassword' psql -h localhost -U genealogy_user -d gramps_monolithic -c "
SELECT
schemaname,
tablename,
pg_size_pretty(pg_total_relation_size(schemaname||'.'||tablename)) as size,
n_live_tup as row_count
FROM pg_stat_user_tables
WHERE tablename LIKE 'tree_%'
ORDER BY pg_total_relation_size(schemaname||'.'||tablename) DESC;"Monolithic Mode (specific tree):
# Backup specific tree's tables
TREE_ID="68932301"
pg_dump -h localhost -U genealogy_user -d gramps_monolithic \
-t "tree_${TREE_ID}_*" -Fc > backup_${TREE_ID}.dumpSeparate Mode (entire database):
# Backup entire tree database
TREE_ID="68932301"
pg_dump -h localhost -U genealogy_user -d ${TREE_ID} -Fc > backup_${TREE_ID}.dump# Restore from backup
pg_restore -h localhost -U genealogy_user -d target_database backup_file.dumpThe addon creates standard Gramps tables with enhanced capabilities:
- Each primary object has both
blob_data(pickle) andjson_data(JSONB) columns - Secondary indexes maintained for Gramps compatibility
- Full referential integrity with foreign keys
- Optimized indexes for genealogical queries
In monolithic mode, all SQL queries are automatically prefixed:
personbecomestree_68932301_person- Handled transparently by
TablePrefixWrapperclass - No changes needed to Gramps queries
- Uses PostgreSQL savepoints for nested transactions
- Automatic rollback on errors
- Maintains full Gramps undo/redo functionality
- ACID compliance for data integrity
- Enables SQL queries on Gramps data structure
- Supports partial updates without full deserialization
- Allows creation of functional indexes
- Enables full-text search across all fields
- Future-proof for advanced analytics
- Enable debug mode for detailed error messages
- Check PostgreSQL logs:
/var/log/postgresql/ - Review debug logs:
~/.gramps/postgresql_enhanced_debug.log - Open an issue on GitHub
Contributions are welcome! Please:
- Follow Gramps coding standards
- Test with large databases
- Update documentation
- Ensure backward compatibility
GNU General Public License v2 or later
Greg Lamberson - greg@aigenealogyinsights.com
Built on the foundation of the Gramps project and the PostgreSQL database system.