Django Can't find table during insert: LINE 1: SELECT 1 AS "a" FROM "qmgr_def_rules" WHERE "qmgr_def_rules"

I'm trying to add a row to my model, but it keeps coming back with:

django.db.utils.ProgrammingError: relation "qmgr_def_rules" does not exist
LINE 1: SELECT 1 AS "a" FROM "qmgr_def_rules" WHERE "qmgr_def_rules"...

Some context: I have 3 different applications under the same django project. I have 2 different postgres schemas: rules and django. The django schema is set to default where all the django specific tables go. The rules schema is for internal data where I can set interval timers, object definitions, etc. I have multiple tables in the rules schema for different types of data.

When I use the admin panel to insert/update/delete on any other table in that schema, it works. Just not def_rules for some odd reason.

A few really odd things:

  • Updates work
  • Deletions work
  • Inserts break with error above through admin panel
  • Inserts work if done through django shell

(this is the shell that I used)

from admin_page.models import QmgrDefRules
from django.utils import timezone

# Try to create a test entry with all required fields
try:
    test_entry = QmgrDefRules(
        # Primary key - required
        qmgr='TEST',
        
        # Required boolean fields (NOT NULL in DDL)
        moni_core_enabled=False,
        moni_inventory_enabled=False,
        qreset=True,  # Has default=true in DDL
        dbinsert_0_value=False,  # Has default=false in DDL
        qsg_monitor=False,  # Has default=false in DDL
        dlqh=False,  # Has default=false in DDL
        smds_monitor=False,  # Has default=false in DDL
        monitor_queuestats=False,  # Has default=false in DDL
        monitor_smds=False,  # Has default=false in DDL
        monitor_rba=False,  # Has default=false in DDL
        monitor_psid_bp=False,  # Has default=false in DDL
        monitor_qhandles=False,  # Has default=false in DDL
        monitor_chstatus_p2p=False,  # Has default=false in DDL
        monitor_chstatus_svrconn=False,  # Has default=false in DDL
        monitor_cfstatus=False,  # Has default=false in DDL
        monitor_chstatus_cluschls=False,  # Has default=false in DDL
        
        # Required integer fields (NOT NULL in DDL)
        rule_refresh_interval_in_sec=60,
        restapi_timeout=5,
        restapi_max_retry=5,
        
        # Optional fields (can be NULL in DDL)
        long_retry_wait_in_sec=600,
        bu='bu',  
        location='test',  
        qsg=None,
        day_alert_from=None,
        day_alert_to=None,
        time_alert_from=None,
        time_alert_to=None,
        email_groups='mail@mail.com',
        page_groups=None,
        mq_rest_url='http://url:port/',
        opsmvs_rest_url=None,
        dlqh_qdepth=None,
        dlqh_msgage=None,
        dlq_name=None,
        last_update=timezone.now(),
        date_created=timezone.now()
    )
    
    # Save to the 'rules' database
    test_entry.save(using='rules')
    print(f" Success! Created QMGR: {test_entry.qmgr}")
    
except Exception as e:
    print(f" Error: {type(e).__name__}: {e}")
    import traceback
    traceback.print_exc()

Here's a model and its admin definition that works:

class QdepthRules(models.Model):
    rule_id = models.AutoField(db_column='id', primary_key=True)
    enabled = models.BooleanField(db_column='enabled')  # Checkbox
    qmgr = models.CharField(db_column='qmgr', max_length=4, validators=[qmgrValidator], help_text='All caps (ex: QQQQ)')  # Field name made lowercase.
    queue = models.CharField(db_column='queue', max_length=45, help_text="Case sensitive. Wildcards allowed.")  # Field name made lowercase.
    threshold = models.IntegerField(db_column='threshold',default=1, validators=[MinValueValidator(1)], help_text="How many messages until MONI alerts.")  # Field name made lowercase.
    day_alert_from = models.IntegerField(db_column='day_alert_from', blank=True, null=True, choices=[(0,"Monday"),(1,"Tuesday"),(2,"Wednesday"),(3,"Thursday"),(4,"Friday"),(5,"Saturday"),(6,"Sunday")])  # Field name made lowercase.
    day_alert_to = models.IntegerField(db_column='day_alert_to', blank=True, null=True, choices=[(0,"Monday"),(1,"Tuesday"),(2,"Wednesday"),(3,"Thursday"),(4,"Friday"),(5,"Saturday"),(6,"Sunday")])  # Field name made lowercase.
    time_alert_from = models.TimeField(db_column='time_alert_from', blank=True, null=True)  # Field name made lowercase.
    time_alert_to = models.TimeField(db_column='time_alert_to', blank=True, null=True)  # Field name made lowercase.
    email_groups = models.TextField(db_column='email_groups', blank=True, null=True, validators=[emailValidator], help_text="Format: mail@mail.com")  # Field name made lowercase.
    page_groups = models.TextField(db_column='page_groups', blank=True, null=True, validators=[pageValidator]")  # Field name made lowercase.
    repeat_alert_val = models.IntegerField(db_column='repeat_alert_val', default=1, validators=[MinValueValidator(1), MaxValueValidator(240)], help_text="How many times the alert needs to trip before sending an alert")  # Field name made lowercase.
    email_page_both = models.CharField(db_column='email_page_both', max_length=45, blank=True, null=True)  # Field name made lowercase.
    last_update = models.DateTimeField(db_column='last_update', blank=True, null=True)  # Field name made lowercase.
    date_created = models.DateTimeField(db_column='date_created', blank=True, null=True)  # Field name made lowercase.

    def __str__(self):
        return f"QMGR: {self.qmgr} - QUEUE: {self.queue} - THRESH: {self.threshold} - ENABLED: {bool(self.enabled)}"

    class Meta:
        managed = False
        db_table = 'qdepth_rules'
        verbose_name_plural = "QDepth_Rules"



---------------------------

from django.contrib import admin

class QDRAdmin(admin.ModelAdmin):
    # fields = ("Title",)

    field_list = []
    for each in QdepthRules._meta.get_fields():
        field_list.append(each.name)

    list_display = field_list
    list_filter = ('date_created',)
    search_fields = ['qmgr','queue']
    readonly_fields = ('date_created','last_update')
    list_display_links = ['rule_id','qmgr','queue']
    
    def get_queryset(self, request):
        return super().get_queryset(request).using('rules')
    
    def save_model(self, request, obj, form, change):
        obj.save(using='rules')
    
    def delete_model(self, request, obj):
        obj.delete(using='rules')
    
    def save_related(self, request, form, formsets, change):
        form.save_m2m()

And heres the one that doesn't:

class QmgrDefRules(models.Model):
    qmgr = models.CharField(primary_key=True,db_column='qmgr', max_length=4, validators=[qmgrValidator], help_text='All caps (ex: QQQQ)')  # Field name made lowercase.
    moni_core_enabled = models.BooleanField(db_column='moni_core_enabled')  # Checkbox
    moni_inventory_enabled = models.BooleanField(db_column='moni_inventory_enabled') # Checkbox
    rule_refresh_interval_in_sec = models.IntegerField(db_column='rule_refresh_interval_in_sec', default=60, help_text="How often (in seconds) MONI checks data against the QMGR.")  # Field name made lowercase.
    long_retry_wait_in_sec = models.IntegerField(db_column='long_retry_wait_in_sec', default=600)  # Field name made lowercase.
    bu = models.CharField(max_length=4)
    location = models.CharField(max_length=10)
    qsg = models.CharField(db_column='qsg', max_length=10, blank=True, null=True)  # Field name made lowercase.
    qsg_monitor = models.BooleanField(help_text='If QMGR is full repository, enable this to collect shared data. Only enable one QMGR per QSG')
    day_alert_from = models.IntegerField(db_column='day_alert_from', blank=True, null=True, choices=[(0,"Monday"),(1,"Tuesday"),(2,"Wednesday"),(3,"Thursday"),(4,"Friday"),(5,"Saturday"),(6,"Sunday")])  # Field name made lowercase.
    day_alert_to = models.IntegerField(db_column='day_alert_to', blank=True, null=True, choices=[(0,"Monday"),(1,"Tuesday"),(2,"Wednesday"),(3,"Thursday"),(4,"Friday"),(5,"Saturday"),(6,"Sunday")])  # Field name made lowercase.
    time_alert_from = models.TimeField(db_column='time_alert_from', blank=True, null=True)  # Field name made lowercase.
    time_alert_to = models.TimeField(db_column='time_alert_to', blank=True, null=True)  # Field name made lowercase.
    email_groups = models.TextField(db_column='email_groups', blank=True, null=True, validators=[emailValidator])  # Field name made lowercase.
    page_groups = models.TextField(db_column='page_groups', blank=True, null=True, validators=[pageValidator])  # Field name made lowercase.
    dbinsert_0_value = models.BooleanField(db_column='dbinsert_0_value', help_text="This will log values into the database even if MSGAGE, CURDEPTH, PUT, and GET are 0. NOTE: THIS SHOULD ONLY BE USED FOR EXTENSIVE TROUBLESHOOTING ONLY.")  # Checkbox
    qreset = models.BooleanField(db_column='qreset', help_text="Enables QRESET for the QMGR. Provides PUT/GET data.")  # Checkbox
    restapi_timeout = models.IntegerField(db_column='restapi_timeout', default=5, help_text="How long (in seconds) MONI waits for a response from the MQ REST API console.")  # Field name made lowercase.
    restapi_max_retry = models.IntegerField(db_column='restapi_max_retry', default=5, help_text="How many times MONI retries to connect to the REST API console if theres an issue connecting before initating a long cooldown.")  # Field name made lowercase.
    mq_rest_url = models.CharField(max_length=50, blank=True, null=True, help_text="URL to the MQ REST API console. Used to connect into the QMGR for data collection. (ex: http://url:port/)")
    opsmvs_rest_url = models.CharField(max_length=50, blank=True, null=True, help_text="URL to the OPSMVS REST API console. Used to send alerts for email/page.)
    dlqh = models.BooleanField(help_text="Enables DLQH for the QMGR.")
    dlqh_qdepth = models.SmallIntegerField(blank=True, null=True, help_text="QDEPTH at which will trigger the DLQH. Can be used with MSGAGE.")
    dlqh_msgage = models.SmallIntegerField(blank=True, null=True, help_text="MSGAGE at which will trigger the DLQH. Can be used with QDEPTH.")
    dlq_name = models.CharField(blank=True, null=True, help_text="DLQ for the QMGR (ex: QTN2.DEAD.QUEUE).")
    last_update = models.DateTimeField(db_column='last_update', blank=True, null=True)  # Field name made lowercase.
    date_created = models.DateTimeField(db_column='date_created', blank=True, null=True)  # Field name made lowercase.
    smds_monitor = models.BooleanField()
    monitor_queuestats = models.BooleanField()
    monitor_smds = models.BooleanField()
    monitor_rba = models.BooleanField()
    monitor_psid_bp = models.BooleanField()
    monitor_qhandles = models.BooleanField()
    monitor_chstatus_p2p = models.BooleanField()
    monitor_chstatus_svrconn = models.BooleanField()
    monitor_cfstatus = models.BooleanField()
    monitor_chstatus_cluschls = models.BooleanField()



    def __str__(self):
        return f"QMGR: {self.qmgr} - RefreshINT: {self.rule_refresh_interval_in_sec} - QSG: {self.qsg} - MONI_CORE_ENABLED: {bool(self.moni_core_enabled)}"

    class Meta:
        managed = False
        db_table = 'qmgr_def_rules'
        verbose_name_plural = "QMGR_DEF_Rules"




---------------------------------------


from django.contrib import admin

class QMGRDRAdmin(admin.ModelAdmin):
    # fields = ("Title",)

    field_list = []
    for each in QmgrDefRules._meta.get_fields():
        field_list.append(each.name)
        
    # print(field_list)
    # print(QmgrDefRules._meta.get_field('qmgr'))

    list_display = field_list
    list_filter = ('date_created',)
    search_fields = ['qmgr','qsg']
    readonly_fields = ('date_created','last_update')
    list_display_links = ['qmgr','qsg']
    
    def get_queryset(self, request):
        return super().get_queryset(request).using('rules')
    
    def save_model(self, request, obj, form, change):
        obj.save(using='rules')
    
    def delete_model(self, request, obj):
        obj.delete(using='rules')
    
    def save_related(self, request, form, formsets, change):
        form.save_m2m()


I've tried so many things at this point that I'm beginning to get demoralized. I tried clearing out the migrations and starting from scratch as well, but that didn't seem to fix the problem unless i've done it incorrectly (which could very well be true).

Вернуться на верх