django-electric


Namedjango-electric JSON
Version 0.1.1 PyPI version JSON
download
home_pageNone
SummaryDjango integration for Electric SQL real-time sync engine
upload_time2025-10-12 19:15:53
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseNone
keywords django electric-sql sync real-time offline-first local-first
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # Django Electric

A Django integration package for [Electric SQL](https://electric-sql.com/), enabling real-time data synchronization between Django applications and client devices.

[![PyPI version](https://badge.fury.io/py/django-electric.svg)](https://badge.fury.io/py/django-electric)
[![Python versions](https://img.shields.io/pypi/pyversions/django-electric.svg)](https://pypi.org/project/django-electric/)
[![Django versions](https://img.shields.io/badge/django-4.2%20%7C%205.0-blue)](https://www.djangoproject.com/)
[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)

## What is Electric SQL?

Electric SQL is a sync engine that enables local-first development with real-time synchronization. Instead of traditional request-response patterns, Electric provides efficient delta-based syncing between your backend database and client applications.

## Features

- **Seamless Django Integration**: Works naturally with Django ORM and existing models
- **Real-time Sync**: Bidirectional synchronization between Django and Electric SQL
- **Shape-based Sync**: Sync specific data subsets using SQL-like filters
- **Offline-First**: Build applications that work offline and sync when connected
- **Type-Safe**: Full type hints and mypy support
- **Battle-Tested**: Comprehensive test suite with pytest
- **Developer-Friendly**: Management commands, admin integration, and decorators
- **Signals Support**: React to sync events with Django signals
- **Caching**: Built-in caching for sync operations

## Installation

```bash
pip install django-electric
```

## Quick Start

### 1. Add to `INSTALLED_APPS`

```python
# settings.py
INSTALLED_APPS = [
    ...
    'django_electric',
    ...
]
```

### 2. Configure Electric SQL

```python
# settings.py

# Electric service URL (required)
ELECTRIC_SERVICE_URL = 'http://localhost:5133'

# Optional settings
ELECTRIC_AUTH_TOKEN = 'your-auth-token'  # If using authentication
ELECTRIC_AUTO_SYNC = True  # Auto-sync on model save
ELECTRIC_SYNC_BATCH_SIZE = 100  # Batch size for sync operations
ELECTRIC_TIMEOUT = 30  # Request timeout in seconds
```

### 3. Update Your Models

```python
from django.db import models
from django_electric.models import ElectricSyncMixin
from django_electric.managers import ElectricManager

class Article(ElectricSyncMixin, models.Model):
    title = models.CharField(max_length=200)
    content = models.TextField()
    published = models.BooleanField(default=False)
    created_at = models.DateTimeField(auto_now_add=True)

    # Use Electric manager for sync capabilities
    objects = ElectricManager()

    class Meta:
        electric_sync = True  # Enable sync for this model
        electric_where = "published = true"  # Only sync published articles
```

### 4. Sync Your Data

```python
# Sync to Electric
result = Article.electric_sync()
print(f"Shape ID: {result['shape_id']}")

# Pull data from Electric
stats = Article.electric_pull()
print(f"Created: {stats['created']}, Updated: {stats['updated']}")

# Get synced data
articles = Article.electric_get_data(limit=50)
```

### 5. Use Management Commands

```bash
# Check Electric status
python manage.py electric_status

# Sync all models
python manage.py electric_sync --all

# Sync specific model
python manage.py electric_sync --model myapp.Article

# Pull data from Electric
python manage.py electric_sync --model myapp.Article --pull
```

## Documentation

### Core Concepts

#### Shape-Based Syncing

Electric SQL uses "shapes" to define what data to sync. A shape is a subset of your data defined by:

- **Table**: Which model/table to sync
- **Where clause**: SQL filter for the data
- **Columns**: Specific fields to include
- **Include**: Related models to sync

```python
# Sync only published articles
Article.electric_sync(where="published = true")

# Sync with specific columns
shape = Article.get_electric_shape(
    columns=['id', 'title', 'created_at']
)
```

#### Model Configuration

Configure sync behavior in your model's `Meta` class:

```python
class Meta:
    electric_sync = True  # Enable sync
    electric_where = "status = 'active'"  # Default filter
    electric_columns = ['id', 'name', 'email']  # Specific columns
```

### API Reference

#### Model Methods

**`Model.electric_sync(where=None, force=False)`**

Sync model to Electric SQL.

```python
Article.electric_sync(where="published = true", force=True)
```

**`Model.electric_pull(where=None, update_existing=True)`**

Pull data from Electric to local database.

```python
stats = Article.electric_pull(where="created_at > '2024-01-01'")
```

**`Model.electric_get_data(where=None, offset=0, limit=100)`**

Get synced data from Electric.

```python
articles = Article.electric_get_data(limit=50)
```

#### Decorators

**`@electric_cached(timeout=300)`**

Cache Electric sync results.

```python
from django_electric.decorators import electric_cached

@electric_cached(timeout=600)
def get_articles():
    return Article.electric_get_data()
```

**`@electric_retry(max_attempts=3, delay=1.0)`**

Retry sync operations on failure.

```python
from django_electric.decorators import electric_retry

@electric_retry(max_attempts=5)
def sync_all_data():
    Article.electric_sync()
    Comment.electric_sync()
```

#### Client API

For advanced usage, use the `ElectricClient` directly:

```python
from django_electric.client import ElectricClient

with ElectricClient() as client:
    # Create a shape
    shape = client.create_shape(
        table="articles",
        where="published = true",
        columns=["id", "title", "content"]
    )

    # Sync the shape
    result = client.sync_shape(shape)

    # Get shape data
    data = client.get_shape_data(result['shape_id'])
```

### Management Commands

#### `electric_status`

Check Electric SQL connection and configuration.

```bash
python manage.py electric_status
```

#### `electric_sync`

Sync models with Electric SQL.

```bash
# Sync all models
python manage.py electric_sync --all

# Sync specific model
python manage.py electric_sync --model blog.Post

# Sync with custom filter
python manage.py electric_sync --model blog.Post --where "published = true"

# Force sync (ignore cache)
python manage.py electric_sync --model blog.Post --force

# Pull data from Electric
python manage.py electric_sync --model blog.Post --pull
```

### Django Admin Integration

Add Electric sync to your admin actions:

```python
from django.contrib import admin
from .models import Article

@admin.register(Article)
class ArticleAdmin(admin.ModelAdmin):
    actions = ['sync_to_electric', 'pull_from_electric']

    def sync_to_electric(self, request, queryset):
        result = Article.electric_sync()
        self.message_user(request, f"Synced: {result}")

    def pull_from_electric(self, request, queryset):
        stats = Article.electric_pull()
        self.message_user(
            request,
            f"Created: {stats['created']}, Updated: {stats['updated']}"
        )
```

### Signals

React to sync events:

```python
from django_electric.signals import (
    electric_sync_started,
    electric_sync_completed,
    electric_sync_failed,
)

@receiver(electric_sync_completed)
def on_sync_complete(sender, **kwargs):
    print(f"Sync completed for {sender.__name__}")

@receiver(electric_sync_failed)
def on_sync_failed(sender, error, **kwargs):
    print(f"Sync failed: {error}")
```

## Examples

See the [examples/demo_project](examples/demo_project) directory for a complete working Django application demonstrating:

- Model configuration with Electric sync
- Management command usage
- Admin panel integration
- API views with sync operations
- Decorator usage

## Development

### Setup Development Environment

```bash
# Clone the repository
git clone https://github.com/Apoorvgarg-Creator/dj-electric.git
cd django-electric

# Create virtual environment
python -m venv venv
source venv/bin/activate  # On Windows: venv\Scripts\activate

# Install in development mode
pip install -e ".[dev]"
```

### Running Tests

```bash
# Run all tests
pytest

# Run with coverage
pytest --cov=django_electric

# Run specific test file
pytest tests/test_client.py

# Run in watch mode
pytest-watch
```

### Code Quality

```bash
# Format code
black .
isort .

# Lint
flake8 django_electric
mypy django_electric

# Type checking
mypy django_electric
```

## Contributing

Contributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.

1. Fork the repository
2. Create a feature branch (`git checkout -b feature/amazing-feature`)
3. Make your changes
4. Add tests for your changes
5. Ensure all tests pass (`pytest`)
6. Commit your changes (`git commit -m 'Add amazing feature'`)
7. Push to the branch (`git push origin feature/amazing-feature`)
8. Open a Pull Request

## Publishing to PyPI

```bash
# Build the package
python -m build

# Upload to PyPI (requires credentials)
twine upload dist/*
```

## Requirements

- Python >= 3.9
- Django >= 4.2
- Electric SQL service running

## License

Apache License 2.0 - see [LICENSE](LICENSE) for details.

## Support

- **Issues**: [GitHub Issues](https://github.com/Apoorvgarg-Creator/dj-electric/issues)
- **Discussions**: [GitHub Discussions](https://github.com/Apoorvgarg-Creator/dj-electric/discussions)
- **Documentation**: [Wiki](https://github.com/Apoorvgarg-Creator/dj-electric/wiki)

## Acknowledgments

- Built for [Electric SQL](https://electric-sql.com/)
- Inspired by local-first and offline-first architectures
- Thanks to the Django and Electric SQL communities

## Roadmap

- [ ] WebSocket support for real-time updates
- [ ] Conflict resolution strategies
- [ ] Multi-tenancy support
- [ ] GraphQL integration
- [ ] Django REST Framework integration
- [ ] Async support with Django 4.2+
- [ ] Schema migration tools
- [ ] Performance monitoring and metrics

---

Made with ❤️ for the Django and Electric SQL communities

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "django-electric",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": "django, electric-sql, sync, real-time, offline-first, local-first",
    "author": null,
    "author_email": "Your Name <your.email@example.com>",
    "download_url": "https://files.pythonhosted.org/packages/24/86/19cbbc07c8e955c574cd2d36292d97ab54cbfe24bf8ac9038467a722f489/django_electric-0.1.1.tar.gz",
    "platform": null,
    "description": "# Django Electric\n\nA Django integration package for [Electric SQL](https://electric-sql.com/), enabling real-time data synchronization between Django applications and client devices.\n\n[![PyPI version](https://badge.fury.io/py/django-electric.svg)](https://badge.fury.io/py/django-electric)\n[![Python versions](https://img.shields.io/pypi/pyversions/django-electric.svg)](https://pypi.org/project/django-electric/)\n[![Django versions](https://img.shields.io/badge/django-4.2%20%7C%205.0-blue)](https://www.djangoproject.com/)\n[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)\n\n## What is Electric SQL?\n\nElectric SQL is a sync engine that enables local-first development with real-time synchronization. Instead of traditional request-response patterns, Electric provides efficient delta-based syncing between your backend database and client applications.\n\n## Features\n\n- **Seamless Django Integration**: Works naturally with Django ORM and existing models\n- **Real-time Sync**: Bidirectional synchronization between Django and Electric SQL\n- **Shape-based Sync**: Sync specific data subsets using SQL-like filters\n- **Offline-First**: Build applications that work offline and sync when connected\n- **Type-Safe**: Full type hints and mypy support\n- **Battle-Tested**: Comprehensive test suite with pytest\n- **Developer-Friendly**: Management commands, admin integration, and decorators\n- **Signals Support**: React to sync events with Django signals\n- **Caching**: Built-in caching for sync operations\n\n## Installation\n\n```bash\npip install django-electric\n```\n\n## Quick Start\n\n### 1. Add to `INSTALLED_APPS`\n\n```python\n# settings.py\nINSTALLED_APPS = [\n    ...\n    'django_electric',\n    ...\n]\n```\n\n### 2. Configure Electric SQL\n\n```python\n# settings.py\n\n# Electric service URL (required)\nELECTRIC_SERVICE_URL = 'http://localhost:5133'\n\n# Optional settings\nELECTRIC_AUTH_TOKEN = 'your-auth-token'  # If using authentication\nELECTRIC_AUTO_SYNC = True  # Auto-sync on model save\nELECTRIC_SYNC_BATCH_SIZE = 100  # Batch size for sync operations\nELECTRIC_TIMEOUT = 30  # Request timeout in seconds\n```\n\n### 3. Update Your Models\n\n```python\nfrom django.db import models\nfrom django_electric.models import ElectricSyncMixin\nfrom django_electric.managers import ElectricManager\n\nclass Article(ElectricSyncMixin, models.Model):\n    title = models.CharField(max_length=200)\n    content = models.TextField()\n    published = models.BooleanField(default=False)\n    created_at = models.DateTimeField(auto_now_add=True)\n\n    # Use Electric manager for sync capabilities\n    objects = ElectricManager()\n\n    class Meta:\n        electric_sync = True  # Enable sync for this model\n        electric_where = \"published = true\"  # Only sync published articles\n```\n\n### 4. Sync Your Data\n\n```python\n# Sync to Electric\nresult = Article.electric_sync()\nprint(f\"Shape ID: {result['shape_id']}\")\n\n# Pull data from Electric\nstats = Article.electric_pull()\nprint(f\"Created: {stats['created']}, Updated: {stats['updated']}\")\n\n# Get synced data\narticles = Article.electric_get_data(limit=50)\n```\n\n### 5. Use Management Commands\n\n```bash\n# Check Electric status\npython manage.py electric_status\n\n# Sync all models\npython manage.py electric_sync --all\n\n# Sync specific model\npython manage.py electric_sync --model myapp.Article\n\n# Pull data from Electric\npython manage.py electric_sync --model myapp.Article --pull\n```\n\n## Documentation\n\n### Core Concepts\n\n#### Shape-Based Syncing\n\nElectric SQL uses \"shapes\" to define what data to sync. A shape is a subset of your data defined by:\n\n- **Table**: Which model/table to sync\n- **Where clause**: SQL filter for the data\n- **Columns**: Specific fields to include\n- **Include**: Related models to sync\n\n```python\n# Sync only published articles\nArticle.electric_sync(where=\"published = true\")\n\n# Sync with specific columns\nshape = Article.get_electric_shape(\n    columns=['id', 'title', 'created_at']\n)\n```\n\n#### Model Configuration\n\nConfigure sync behavior in your model's `Meta` class:\n\n```python\nclass Meta:\n    electric_sync = True  # Enable sync\n    electric_where = \"status = 'active'\"  # Default filter\n    electric_columns = ['id', 'name', 'email']  # Specific columns\n```\n\n### API Reference\n\n#### Model Methods\n\n**`Model.electric_sync(where=None, force=False)`**\n\nSync model to Electric SQL.\n\n```python\nArticle.electric_sync(where=\"published = true\", force=True)\n```\n\n**`Model.electric_pull(where=None, update_existing=True)`**\n\nPull data from Electric to local database.\n\n```python\nstats = Article.electric_pull(where=\"created_at > '2024-01-01'\")\n```\n\n**`Model.electric_get_data(where=None, offset=0, limit=100)`**\n\nGet synced data from Electric.\n\n```python\narticles = Article.electric_get_data(limit=50)\n```\n\n#### Decorators\n\n**`@electric_cached(timeout=300)`**\n\nCache Electric sync results.\n\n```python\nfrom django_electric.decorators import electric_cached\n\n@electric_cached(timeout=600)\ndef get_articles():\n    return Article.electric_get_data()\n```\n\n**`@electric_retry(max_attempts=3, delay=1.0)`**\n\nRetry sync operations on failure.\n\n```python\nfrom django_electric.decorators import electric_retry\n\n@electric_retry(max_attempts=5)\ndef sync_all_data():\n    Article.electric_sync()\n    Comment.electric_sync()\n```\n\n#### Client API\n\nFor advanced usage, use the `ElectricClient` directly:\n\n```python\nfrom django_electric.client import ElectricClient\n\nwith ElectricClient() as client:\n    # Create a shape\n    shape = client.create_shape(\n        table=\"articles\",\n        where=\"published = true\",\n        columns=[\"id\", \"title\", \"content\"]\n    )\n\n    # Sync the shape\n    result = client.sync_shape(shape)\n\n    # Get shape data\n    data = client.get_shape_data(result['shape_id'])\n```\n\n### Management Commands\n\n#### `electric_status`\n\nCheck Electric SQL connection and configuration.\n\n```bash\npython manage.py electric_status\n```\n\n#### `electric_sync`\n\nSync models with Electric SQL.\n\n```bash\n# Sync all models\npython manage.py electric_sync --all\n\n# Sync specific model\npython manage.py electric_sync --model blog.Post\n\n# Sync with custom filter\npython manage.py electric_sync --model blog.Post --where \"published = true\"\n\n# Force sync (ignore cache)\npython manage.py electric_sync --model blog.Post --force\n\n# Pull data from Electric\npython manage.py electric_sync --model blog.Post --pull\n```\n\n### Django Admin Integration\n\nAdd Electric sync to your admin actions:\n\n```python\nfrom django.contrib import admin\nfrom .models import Article\n\n@admin.register(Article)\nclass ArticleAdmin(admin.ModelAdmin):\n    actions = ['sync_to_electric', 'pull_from_electric']\n\n    def sync_to_electric(self, request, queryset):\n        result = Article.electric_sync()\n        self.message_user(request, f\"Synced: {result}\")\n\n    def pull_from_electric(self, request, queryset):\n        stats = Article.electric_pull()\n        self.message_user(\n            request,\n            f\"Created: {stats['created']}, Updated: {stats['updated']}\"\n        )\n```\n\n### Signals\n\nReact to sync events:\n\n```python\nfrom django_electric.signals import (\n    electric_sync_started,\n    electric_sync_completed,\n    electric_sync_failed,\n)\n\n@receiver(electric_sync_completed)\ndef on_sync_complete(sender, **kwargs):\n    print(f\"Sync completed for {sender.__name__}\")\n\n@receiver(electric_sync_failed)\ndef on_sync_failed(sender, error, **kwargs):\n    print(f\"Sync failed: {error}\")\n```\n\n## Examples\n\nSee the [examples/demo_project](examples/demo_project) directory for a complete working Django application demonstrating:\n\n- Model configuration with Electric sync\n- Management command usage\n- Admin panel integration\n- API views with sync operations\n- Decorator usage\n\n## Development\n\n### Setup Development Environment\n\n```bash\n# Clone the repository\ngit clone https://github.com/Apoorvgarg-Creator/dj-electric.git\ncd django-electric\n\n# Create virtual environment\npython -m venv venv\nsource venv/bin/activate  # On Windows: venv\\Scripts\\activate\n\n# Install in development mode\npip install -e \".[dev]\"\n```\n\n### Running Tests\n\n```bash\n# Run all tests\npytest\n\n# Run with coverage\npytest --cov=django_electric\n\n# Run specific test file\npytest tests/test_client.py\n\n# Run in watch mode\npytest-watch\n```\n\n### Code Quality\n\n```bash\n# Format code\nblack .\nisort .\n\n# Lint\nflake8 django_electric\nmypy django_electric\n\n# Type checking\nmypy django_electric\n```\n\n## Contributing\n\nContributions are welcome! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for details.\n\n1. Fork the repository\n2. Create a feature branch (`git checkout -b feature/amazing-feature`)\n3. Make your changes\n4. Add tests for your changes\n5. Ensure all tests pass (`pytest`)\n6. Commit your changes (`git commit -m 'Add amazing feature'`)\n7. Push to the branch (`git push origin feature/amazing-feature`)\n8. Open a Pull Request\n\n## Publishing to PyPI\n\n```bash\n# Build the package\npython -m build\n\n# Upload to PyPI (requires credentials)\ntwine upload dist/*\n```\n\n## Requirements\n\n- Python >= 3.9\n- Django >= 4.2\n- Electric SQL service running\n\n## License\n\nApache License 2.0 - see [LICENSE](LICENSE) for details.\n\n## Support\n\n- **Issues**: [GitHub Issues](https://github.com/Apoorvgarg-Creator/dj-electric/issues)\n- **Discussions**: [GitHub Discussions](https://github.com/Apoorvgarg-Creator/dj-electric/discussions)\n- **Documentation**: [Wiki](https://github.com/Apoorvgarg-Creator/dj-electric/wiki)\n\n## Acknowledgments\n\n- Built for [Electric SQL](https://electric-sql.com/)\n- Inspired by local-first and offline-first architectures\n- Thanks to the Django and Electric SQL communities\n\n## Roadmap\n\n- [ ] WebSocket support for real-time updates\n- [ ] Conflict resolution strategies\n- [ ] Multi-tenancy support\n- [ ] GraphQL integration\n- [ ] Django REST Framework integration\n- [ ] Async support with Django 4.2+\n- [ ] Schema migration tools\n- [ ] Performance monitoring and metrics\n\n---\n\nMade with \u2764\ufe0f for the Django and Electric SQL communities\n",
    "bugtrack_url": null,
    "license": null,
    "summary": "Django integration for Electric SQL real-time sync engine",
    "version": "0.1.1",
    "project_urls": {
        "Documentation": "https://github.com/Apoorvgarg-Creator/dj-electric/wiki",
        "Homepage": "https://github.com/Apoorvgarg-Creator/dj-electric",
        "Issues": "https://github.com/Apoorvgarg-Creator/dj-electric/issues",
        "Repository": "https://github.com/Apoorvgarg-Creator/dj-electric"
    },
    "split_keywords": [
        "django",
        " electric-sql",
        " sync",
        " real-time",
        " offline-first",
        " local-first"
    ],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5fe4ba25fc8bf2086069929a8462bafbf0173b0a5d41d8fd84c0578a25205b0c",
                "md5": "c8db84f762962d8fbcb36e61a9458ea0",
                "sha256": "ec723f11ebcc145b734c10588c800c1211663446fbbfaf7715fa576cad17a1d1"
            },
            "downloads": -1,
            "filename": "django_electric-0.1.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "c8db84f762962d8fbcb36e61a9458ea0",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 25654,
            "upload_time": "2025-10-12T19:15:51",
            "upload_time_iso_8601": "2025-10-12T19:15:51.969898Z",
            "url": "https://files.pythonhosted.org/packages/5f/e4/ba25fc8bf2086069929a8462bafbf0173b0a5d41d8fd84c0578a25205b0c/django_electric-0.1.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "248619cbbc07c8e955c574cd2d36292d97ab54cbfe24bf8ac9038467a722f489",
                "md5": "1acd687b93f9f65d94fdca04b0ad4deb",
                "sha256": "3c64e4e63e85031491a3099873903deada7f25a76171dfe2b7ea8bf81ed26c18"
            },
            "downloads": -1,
            "filename": "django_electric-0.1.1.tar.gz",
            "has_sig": false,
            "md5_digest": "1acd687b93f9f65d94fdca04b0ad4deb",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 26633,
            "upload_time": "2025-10-12T19:15:53",
            "upload_time_iso_8601": "2025-10-12T19:15:53.146203Z",
            "url": "https://files.pythonhosted.org/packages/24/86/19cbbc07c8e955c574cd2d36292d97ab54cbfe24bf8ac9038467a722f489/django_electric-0.1.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-10-12 19:15:53",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "github_user": "Apoorvgarg-Creator",
    "github_project": "dj-electric",
    "travis_ci": false,
    "coveralls": false,
    "github_actions": true,
    "lcname": "django-electric"
}
        
Elapsed time: 1.58684s