Declarative Models¶
When you need to generate a declarative_model
from an SQLAlchemy ORM type, you can easily do so by calling Model.declarative()
. For example, User.declarative()
. This method automatically generates the declarative model type for you, allowing seamless integration with SQLAlchemy's ecosystem.
import edgy
from edgy import Database, Registry
database = Database("sqlite:///db.sqlite")
models = Registry(database=database)
# Declare the Edgy model
class User(edgy.Model):
is_active: bool = edgy.BooleanField(default=True)
first_name: str = edgy.CharField(max_length=50)
last_name: str = edgy.CharField(max_length=50)
email: str = edgy.EmailField(max_lengh=100)
password: str = edgy.CharField(max_length=1000)
class Meta:
registry = models
# Generate the declarative version
UserModelDeclarative = User.declarative()
It's crucial to understand the implications of using a declarative model, especially when dealing with ForeignKey or OneToOneField relationships. Edgy automatically generates an SQLAlchemy Relationship and appends _relation
to the end of the declared field.
Let's illustrate this with a practical example.
import edgy
from edgy import Database, Registry
database = Database("sqlite:///db.sqlite")
models = Registry(database=database)
class User(edgy.Model):
is_active: bool = edgy.BooleanField(default=True)
first_name: str = edgy.CharField(max_length=50)
last_name: str = edgy.CharField(max_length=50)
email: str = edgy.EmailField(max_lengh=100)
password: str = edgy.CharField(max_length=1000)
class Meta:
registry = models
class Thread(edgy.Model):
sender: User = edgy.ForeignKey(
User,
on_delete=edgy.CASCADE,
related_name="sender",
)
receiver: User = edgy.ForeignKey(
User,
on_delete=edgy.CASCADE,
related_name="receiver",
)
message: str = edgy.TextField()
class Meta:
registry = models
In the Thread
model, you'll notice two foreign keys, sender
and receiver
. In standard Edgy ORM operations, these fields remain as declared. However, when you generate the declarative()
model from Edgy, it automatically creates the following additional fields:
sender_relation
receiver_relation
These auto-generated _relation
fields are SQLAlchemy relationships that provide a more direct way to interact with related data within the SQLAlchemy context.
Why are these _relation
fields generated?¶
The primary reason for this behavior is to facilitate compatibility and interoperability with tools and libraries that rely on SQLAlchemy's declarative models. While Edgy focuses on providing a high-level, asynchronous ORM, there are scenarios where deeper integration with SQLAlchemy's features is necessary.
For instance, libraries like Esmerald Admin leverage Edgy's declarative models to provide admin interfaces that can efficiently manage related data. These tools expect SQLAlchemy relationships to be available, and Edgy's declarative()
method ensures that these relationships are generated automatically.
Impact on Edgy's Core Functionality¶
It's important to note that these _relation
fields do not alter or impact Edgy's core functionality. They are purely for compatibility with SQLAlchemy-based tools. When you use Edgy's querysets and model methods, you interact with the original sender
and receiver
fields as you normally would.
Practical Implications and Use Cases¶
- Integration with SQLAlchemy-based tools: If you're using tools or libraries that rely on SQLAlchemy's declarative models, generating
declarative()
models from Edgy ensures seamless integration. - Admin interfaces: Tools like Esmerald Admin, which utilize Edgy's declarative models, can efficiently manage related data through the generated SQLAlchemy relationships.
- Advanced SQLAlchemy features: If you need to leverage advanced SQLAlchemy features that require direct access to relationships, generating
declarative()
models provides the necessary access.
When to Use declarative()
¶
In most cases, you won't need to explicitly generate declarative()
models. Edgy's ORM provides a comprehensive set of features for managing data without requiring direct access to SQLAlchemy's declarative models.
However, if you're working with tools or libraries that require SQLAlchemy relationships, or if you need to leverage advanced SQLAlchemy features, generating declarative()
models can be beneficial.
Key Takeaways¶
- Edgy's
declarative()
method generates SQLAlchemy declarative models, providing compatibility with SQLAlchemy-based tools. - ForeignKey and OneToOneField relationships result in the automatic generation of
_relation
fields, which are SQLAlchemy relationships. - These
_relation
fields do not impact Edgy's core functionality and are primarily for compatibility with external tools.