2

History: I have been using GNUCash for Accounting and it stores all customer information so to integrate Job Delivery of files and invoices i was integrating GNUCash database on Postgres with the existing local server to send and backup files and mark them automatically.

So i did inspectdb> models.py and got all the models from gnucash database. Now 'Customers.objects.all()' is working file and gives list of all the data but 'Customers.objects.get()' doesn't work and gives error.

View:

def get_job_list(client_id):
    try:
        client = Customers.objects.get(id = client_id).using('gnucash')
        print(client)
        ###job_list = Jobs.objects.get(owner_guid = client.guid,active = 0).using('gnucash')
    except Exception as e:
        job_list = None

    return job_list

Error: Error When Using Model.objects.get()

The above error states that the table doesn't exist customers. But when i change the code to Model.objects.all() it works fine.

View:

def get_job_list(client_id):
    try:
        client = Customers.objects.all().using('gnucash') #This is Changed
        print(client)
        job_list = None
        ###job_list = Jobs.objects.get(owner_guid = client.guid,active = 0).using('gnucash')
    except Exception as e:
        job_list = None

    return job_list

Output: Success output for Model.objects.all()

I looked at This question which focuses on lowecase table name which is correct for me as .all() work but not .get(). Here is model if you want to take a look:

class Customers(models.Model):
    guid = models.CharField(primary_key=True, max_length=32)
    name = models.CharField(max_length=2048)
    id = models.CharField(max_length=2048)
    notes = models.CharField(max_length=2048)
    active = models.IntegerField()
    .
    .
    .
    class Meta:
        managed = False
        db_table = 'customers'

Table Name in DB pgAdmin: Table Customers

Table List: Using \dt \dt list of database tables

Using Hardcoded Values in .get as suggested by @boyenec:

def get_job_list(client_id):
    try:
        print("Getting Jobs List")
        #client = Customers.objects.filter(id__in=[client_id]).using('gnucash')
        client = Customers.objects.get(id = "CUS000001").using('gnucash')
        #job_list = Jobs.objects.filter(owner_guid__in = [client[0].guid],active__in = [1]).using('gnucash')
    except Exception as e:
        print("Oh No Error !")
        print(e)
        job_list = None
    return job_list

Error Output: Error even with hardcoded values

App ERP registered with Admin site: Admin site error due to fallback to default DB UPDATE:DO NOT USE THIS CHECK OUT THE ANSWER IT SOLVES THE PROBLEM

I Started using client = Customers.objects.filter(id__in=[client_id]).using('gnucash') for the queries as everything seem to work other than Model.objects.get()

Dushyant Deshwal
  • 388
  • 4
  • 17

2 Answers2

1

When you are using objects.get, it mean you are trying to find specific object. You must include the specific object id or value. You can't use variable like client_id, name etc inside objects.get. See the django documentation. Instead of using client_id or name you need to be use actual client id or name such as 1,2,3,"jhone","Mike". When you are using this

client = Customers.objects.get(id = client_id).using('gnucash')

your are telling get the client_id but you are not telling which client_id. So you are getting the error. You need to be specify client id something like this

#example1

client = Customers.objects.get(pk=1).using('gnucash')

#example2

 client = Customers.objects.get(name="jhone").using('gnucash') #it will return the customer whose name is jone.

When you are using get_all() it's returning all objects so you are not getting the error and filter is different from objects.get. You can use the variable like client_id in filter but you can't do it with objects.get.

Normally we use objects.get for find any specific object. Let assume you have 100 customer and you want to find only customers those belongs from specific region or place or we want to find only female customers. Then we will use objects.get.

#find customers those only belongs from Arizona

     client = Customers.objects.get(place="arizona")

#find only female customers
     client = Customers.objects.get(gender="female")

You can do same things by using filter and objects.get_all() but above example help you to understand concept of objects.get()

boyenec
  • 1,405
  • 5
  • 29
  • I understand where you are going with this. Unfortunately that is not the problem. I did check it with hard coded "CUS000001" and it gave the same error. On the other hand you can do `id = client_id ` if both data types are same and if you want to be sure do str(client_id) if your model field is char type and do int(client_id) if your model field is integer type. Documentation shows that you need the same type of data to compare. – Dushyant Deshwal Jun 19 '21 at 01:21
  • 1
    Can I see your hard coded which did for "CUS000001"? You should get the result without any errors. You might be doing mistake somewhere – boyenec Jun 19 '21 at 07:11
  • Sure, I added the required view and output towards the end before update. – Dushyant Deshwal Jun 19 '21 at 07:44
  • 1
    Can you please also try name="your coustomer name" and let me know the results. Can you show one row of customer table ? – boyenec Jun 19 '21 at 09:21
  • Go to your django admin panel and copy the customer id and paste in your code and let me know the result. It will be better if I can see one row of your coustomer table. – boyenec Jun 19 '21 at 09:45
  • Added the error i got by registering the app in admin. I believe that is there because it is using default DB but not sure why it would do when it was clearly mention `.using("gnucash")`. – Dushyant Deshwal Jun 19 '21 at 21:38
  • Thanks boyenec. We were barking the wrong tree.I was sure that if i have mentioned `Model.objects.get().using('gnucash')` then it should use gnucash but everything from filter to all were working with `.using('gnucash')` but not `get`. it always fell back to default database.We found the problem and a possible bug maybe. – Dushyant Deshwal Jun 19 '21 at 21:54
0

When using a non managed database in django(not managed or not created by django) Model.objects.filter().using('gnucash') and Model.objects.all().using('gnucash') seemed to work but not Model.objects.get().using('gnucash').

As @boyenec was suggesting to copy the value of Customers from django admin panel to be sure that we have the right value. I knew that admin panel will only work with a database router because there is no .using() added to admin site.

Database routers sorted the error but for which i had to refer the documentation, i went to the documentation and found out that it is not Model.objects.get().using('gnucash') but rather Model.objects.using('gnucash').get() it somehow works for filter but for get() it was not working.

Put .using('dbname') after Model.objects and not after .get().

Documentation for multiple database django 3.2

Dushyant Deshwal
  • 388
  • 4
  • 17