I have one entries table on which I have to loop over 40k records and show their data in table. As that table is related to three foreign key data, I tried to add those data in the base query itself to reduce extra queries.
I think my base query containing something like <Model: Customer>
which is causing the issue.
lets say this are my classes
class BaseModel(Model):
class Meta:
database = database
class Customer(BaseModel):
name = TextField()
class Farmer(BaseModel):
name = TextField(null=False)
class Product(BaseModel):
name = TextField()
class Entries(BaseModel):
farmer = ForeignKeyField(Farmer, backref='entries')
customer = ForeignKeyField(Customer, backref='entries')
product = ForeignKeyField(Product, backref='product')
other = TextField()
class Meta:
table_name = 'entries'
The query I tried
entries = Entries.select(
Entries,
Farmer.name.alias('farmer_name'),
Customer.name.alias('customer_name'),
Product.name.alias('product_name')
).join(Farmer, Customer, Product)
It generates the sql
SELECT "t1"."id", "t1"."farmer_id", "t1"."customer_id", "t1"."product_id", "t1"."other", "t2"."name" AS "farmer_name", "t3"."name" AS "customer_name", "t4"."name" AS "product_name" FROM "entries" AS "t1" <Model: Customer> "farmer" AS "t2" ON "product" AS "t4"
I also tried seperate joins using switch method but no success.
Is it possible to fetch the data within same instance or I have to do seperate queries only?
When I do the following query with dicts()
, it works fine, but without it, it shows AttributeError: 'Entries' object has no attribute 'farmer_name'
.
Query:
entries = Entries.select(
Entries,
Farmer.name.alias('farmer_name'),
Customer.name.alias('customer_name'),
Product.name.alias('product_name')
).join(Farmer, on=(Entries.farmer == Farmer.id)) \
.join(Customer, on=(Entries.customer == Customer.id)) \
.join(Product, on=(Entries.product == Product.id))
Peewee, by default, will put those aliases on the actual joined model, e.g.
entries = (Entries
.select(
Entries,
Farmer.name.alias('farmer_name'),
Customer.name.alias('customer_name'),
Product.name.alias('product_name'))
.join_from(Entry, Farmer)
.join_from(Entry, Customer)
.join_from(Entry, Product))
for e in entries:
print(e.farmer.farmer_name, e.customer.customer_name) # etc
If you just want everything on the entry, then add ".objects()" which prevents the graph generation and slaps everything on "Entry":
for e in entries.objects(): # Added .objects()
print(e.farmer_name, e.customer_name) # etc
Doc: http://docs.peewee-orm.com/en/latest/peewee/relationships.html#selecting-from-multiple-sources