edgy ORM Documentation

repository·main·Indexed 19 days ago

https://github.com/dymmond/edgy

A high-performance, framework-agnostic ORM built on SQLAlchemy Core that leverages Pydantic for automatic data validation and schema management. It features a comprehensive CLI for migrations (via Alembic), a built-in Admin Web GUI for database inspection, and support for multiple database drivers including Postgres, MySQL/MariaDB, SQLite, and MSSQL.

Tokens
82.1K
Snippets
269
Records
414
Agent score
65%

What's inside edgy

  1. Navigate the Edgy API Reference

    main

    The Edgy API documentation is organized into narrative guides for conceptual understanding and a reference map for specific method/attribute details.

    For conceptual learning, follow these narrative guides:

    • Edgy Core: General overview and usage.
    • Models: How to define and use data models.
    • Queries: How to interact with data using query sets.
    • Migrations: How to manage database schema changes.

    For specific technical details, use the Reference Map:

    • Data layer: Model, ReflectModel, Manager, QuerySet
    • Schema and DB: Registry, Schema, Database
    • Fields: Base field API and relationship fields (e.g., ForeignKey, ManyToMany)
    • Signals: Low-level signal type reference.
  2. What is a model in Edgy

    main

    In Edgy, a model is a Python class that serves a dual purpose:

    1. It represents a database table using SQLAlchemy core.
    2. It acts as a Pydantic model, enabling data validation and serialization.

    This allows you to use the same class for both database interactions and data handling within your application logic.

  3. What is a Related Name in Edgy?

    main

    A related_name is an attribute declared within a ForeignKey that specifies the name of the reverse relation from the related model back to the model defining the relation. It designates the attribute name used to access the related model from the opposite side of the relationship.

    There are two ways to define a related name:

    1. Explicit Parameter: Directly declaring the related_name attribute within the ForeignKey definition.
    2. Automatic Generation: If no related_name is provided, Edgy automatically generates the name based on the related model's lowercase name:
      • For non-unique relations: <table-name>s_set (e.g., organisations_set).
      • For unique relations: <table-name> (e.g., organisation).
  4. What is Reflection in Edgy?

    main
    Reflection allows you to represent existing database tables and views as models in your code without recreating them. This is particularly useful for working with legacy databases. Edgy reads the existing structure and mirrors it in your models, effectively converting database columns into Edgy model fields.
  5. What is a Reference ForeignKey (RefForeignKey)?

    main

    A RefForeignKey is a specialized field in Edgy designed to simplify the creation of related records during insertion.

    Key Characteristics:

    • No Database Constraint: Unlike a standard ForeignKey, it does not create a foreign key constraint in the database. It is an internal Edgy mechanism for automated record insertion.
    • Insertion Only: It is strictly used for creating new records. It is not used for updating existing ones.
    • Always Creates New Records: Even when calling save(), a RefForeignKey will attempt to create new records rather than updating existing ones. Use caution to avoid unintended duplicates.
    • Internal Mapping: It acts as a mapper that facilitates automated insertion of related models.
  6. What is the Registry and how does it work?

    main

    The Registry is the central object in the Edgy ORM used to specify database connections. It acts as a mapping between your models and the database where data is stored. It is also used for generating migrations with Alembic.

    In the Edgy topology, the Registry manages:

    • The Main Database
    • Extra Databases (additional connections)
    • The Model Registry (which includes SQLAlchemy Metadata and model callbacks)
    • Schema operations
  7. Configure primary keys and ID generation

    main

    Edgy has specific behaviors regarding IDs:

    • Automatic ID: If no id is declared, Edgy automatically generates an id of type BigIntegerField and sets it as the primary key.
    • Custom Primary Keys: You can declare a primary key different from the default id (e.g., a UUIDField).
    • Manual ID: If you declare an id that is not an IntegerField or BigIntegerField, you must provide the primary key manually when creating the object.
    • Autoincrement Warning: For backward compatibility, IntegerField or BigIntegerField declared as primary keys have autoincrement=True by default. You must explicitly set autoincrement=False to disable it. Note that only one field per model can have autoincrement=True.
  8. Use abstract models for common functionality

    main

    Abstract models allow you to define common fields and methods without creating a database table. Set abstract = True in the Meta class.

    Limitations of Abstract Models:

    • You cannot declare managers in an abstract model.
    • You cannot declare unique_together constraints in an abstract model.
  9. Annotate grandchild elements using `reference_select` and `embed_parent`

    main
    If you are using embed_parent to include parent data when fetching related children, you can still augment grandchild elements with additional parent attributes. Because reference_select executes before the embedding process, you can use it to add parent attributes to the data available at the grandchild level in deeply nested relationships.
  10. Manage QuerySet cache

    main

    Edgy caches certain query results. Methods like first(), last(), and count() are always cached and initialized when iterating over a query or requesting all results. Other filtering functions can also utilize the cache by providing filters as keywords or leaving arguments empty.

    To clear the cache for a specific QuerySet, use the .all(True) method.

    users = User.query.all().filter(name="foobar")
    # clear the cache
    users.all(True)
    await users
  11. Use Embeddable Models for automatic composition

    main

    You can embed one Edgy model within another by assigning the model class to a field. Edgy automatically copies the fields from the embedded model into the parent model, prefixing each field name with the attribute name followed by an underscore (_).

    To prevent specific fields (like PKField or auto-injected id fields) from being copied, or to prevent fields from being inherited by submodels, set inherit = False in the embedded model's Meta class.

    Key behaviors:

    • Automatic Prefixing: If you embed InheritableModel as model1, its first_name field becomes model1_first_name in the parent model.
    • Inheritance Control: If an embedded model has inherit = False in its Meta, its fields will not be passed down to models that inherit from the parent model.
    import edgy
    from typing import ClassVar
    
    class InheritableModel(edgy.Model):
        first_name: str = edgy.CharField(max_length=255)
        last_name: str = edgy.CharField(max_length=255)
    
        class Meta:
            abstract = True
    
    class NonInheritableModel(edgy.Model):
        age: int = edgy.IntegerField()
        class Meta:
            abstract = True
            inherit = False
    
    class MyModel(edgy.Model):
        # ClassVar is optional; fields are prefixed with 'model1_' and 'model2_'
        model1: ClassVar[InheritableModel] = InheritableModel
        model2 = NonInheritableModel
    
    class AnotherModel(MyModel):
        pass
        # Because NonInheritableModel had inherit=False, model2 fields are NOT in AnotherModel
  12. Integrate Edgy into libraries and middleware

    main

    When building libraries or ASGI middleware (e.g., for a Django project), you can integrate Edgy using two primary patterns:

    1. Extensions

    Add an extension to your EdgySettings. This extension injects your library's models into the main application's registry.

    • Pros: Reuses the existing registry and database; migrations include the injected models.
    • Cons: Requires Edgy to be the main application; limited to one registry; tightly coupled to the main application's settings.

    2. Automigrations

    Provide an extra registry by filling the automigrate_config parameter with an EdgySettings object or string.

    • Pros: Completely independent registry and database; ideal for ASGI middleware; can be fully automated.
    • Cons: Requires DDL (Data Definition Language) permissions on the database. If using Alembic's offline mode, libraries must be accessed manually via edgy migrate -d librarypath/migrations.

    Note: If the environment lacks DDL permissions, you can disable this feature by setting allow_automigrations=False in your Edgy settings.