Sequence Generation Troubleshooting

Developer guide for the Enezaframework sequence generation. Part of the Sequence Generation series.

Table of Contents

  1. Overview
  2. Common Issues
  3. Debugging Steps
  4. Error Messages
  5. Performance Considerations
  6. Migration Considerations
  7. Related Guides

Overview

Nearly every sequence problem is one of four things: a missing attribute on the model, no active SequenceConfig, a wrong number_length, or a duplicate/mismatched document_name. The mixin fails loudly (ValueError) when it cannot generate, so start from the exception message.

flowchart TD
    SYM["Sequence not generated"] --> A{"sequence_field_name and<br/>document_name set?"}
    A -->|No| FIX1["Add both attributes"]
    A -->|Yes| B{"Field nullable?"}
    B -->|No| FIX2["Set null=True, blank=True"]
    B -->|Yes| C{"Active SequenceConfig<br/>for document_name?"}
    C -->|No| FIX3["Create one in admin"]
    C -->|Yes| D{"number_length correct?"}
    D -->|No| FIX4["Adjust length"]
    D -->|Yes| FIX5["Check duplicates / concurrency"]

Common Issues

Sequence field remains empty after saving Cause: missing sequence_field_name or document_name. Solution: set both on the model.

python
class MyModel(EnezaMaster):
    my_field = models.CharField(
        max_length=50,
        null=True,
        blank=True,
        verbose_name="My Field",
    )

    sequence_field_name = 'my_field'
    document_name = ProjectDocumentTypes.MY_TYPE

Double inheritance / MRO problems Cause: inheriting SequenceMixin explicitly alongside EnezaMaster/EnezaDocument. Solution: inherit only the base model.

"No Sequence configuration found" error Cause: no active config for the document type. Solution: create an active config in admin, or fix the document_name so it matches an existing config.

Duplicate sequence numbers Cause: multiple active configs, or concurrent writes racing the read-modify-write. Solution: ensure a single active config per document (enforced by the unique constraint), and serialize generation for concurrency.

Format mismatch (CUST-1 instead of CUST-0001) Cause: wrong number_length. Solution: set the desired length in the config.

Manual value overwritten? Cause: a value was expected to be auto-generated but one is already set. Solution: the mixin never overwrites a non-empty field; clear the field to let generation run.


Debugging Steps

  1. Check the model attributes

python print(MyModel.sequence_field_name) # field name print(MyModel.document_name) # document type value

  1. Check the configuration

```python from enezaframework.models.enezasequence import SequenceConfig

config = SequenceConfig.objects.filter( documents=MyModel.document_name, active=True, ).first()

print(config) # must not be None ```

  1. Check field assignment

python obj = MyModel() obj.save() print(obj.my_field) # should contain the generated sequence

  1. Check the choices loader — if admin does not show your document type, verify MY_PROJECT_NUMBER_SEQUENCE_DOCUMENT imports. See Sequence Settings Configuration.

Error Messages

Message Meaning Fix
No Sequence configuration found for model 'X'. Please set up the sequence configuration under System Administrator. No active config for document_name. Create an active SequenceConfig, or correct document_name.
Failed to generate sequence for field 'Y' in model 'X'. generate_sequence() returned an empty value. Check the config's prefix/length and any custom generate_sequence().
Could not import <path>: ... Using default choices. The choices setting path is wrong. Fix the dotted path in settings.py.
sequenceDiagram
    participant M as Model.save()
    participant G as generate_sequence()
    participant DB as SequenceConfig

    M->>G: field empty on new object
    G->>DB: filter(documents, active=True).first()
    alt no config
        DB-->>G: None
        G-->>M: ValueError "No Sequence configuration found..."
    else config
        DB-->>G: config
        G-->>M: "PREFIX-0001"
    end

Performance Considerations

  • Each save performs one SELECT (the config) and one UPDATE (nextnumber), plus the model's own INSERT/UPDATE.
  • For bulk creation, the per-record round trip adds up — consider pre-generating numbers or a custom bulk path.
  • The SequenceConfig row is written on every generation, so watch for lock contention on that row under load.

Migration Considerations

To migrate existing data to sequences:

  1. Add the sequence field with null=True.
  2. Populate existing records with their manual numbers.
  3. Create a SequenceConfig whose nextnumber continues after the existing maximum.
  4. Add sequence_field_name and document_name to the model.
  5. Handle existing rows carefully: because the mixin only generates for new objects, existing rows are left untouched — good for backfill.
flowchart LR
    A["Add nullable field"] --> B["Backfill existing numbers"]
    B --> C["Set nextnumber after max"]
    C --> D["Add attributes to model"]
    D --> E["New records auto-number"]

For related migration topics, see Sequence Configuration Model and Base Models & Model Types.