How to INSERT into a database using JOIN

Viewed 84

I'm currently using PeeWee together with Python and I have managed to create a cool application

CREATE TABLE stores (
    id SERIAL PRIMARY KEY,
    store_name TEXT
);


CREATE TABLE products (
    id SERIAL, 
    store_id INTEGER NOT NULL,
    title TEXT,
    image TEXT,
    url TEXT UNIQUE, 
    added_date timestamp without time zone NOT NULL DEFAULT NOW(),
    PRIMARY KEY(id, store_id)
);


ALTER TABLE products
ADD  CONSTRAINT "FK_products_stores" FOREIGN KEY ("store_id")
        REFERENCES stores (id) MATCH SIMPLE
        ON UPDATE NO ACTION
        ON DELETE RESTRICT;

which has been converted to peewee by following code:

# ------------------------------------------------------------------------------- #
class Stores(Model):
    id = IntegerField(column_name='id')
    store_name = TextField(column_name='store_name')

    class Meta:
        database = postgres_pool
        db_table = "stores"

    @classmethod
    def get_all(cls):
        try:
            return cls.select(cls.id, cls.store_name).order_by(cls.store)
        except Stores.IntegrityError:
            return None


# ------------------------------------------------------------------------------- #
class Products(Model):
    id = IntegerField(column_name='id')
    title = TextField(column_name='title')
    url = TextField(column_name='url')
    image = TextField(column_name='image')
    store = ForeignKeyField(Stores, backref='products')

    class Meta:
        database = postgres_pool
        db_table = "products"

    @classmethod
    def add_product(cls, pageData, store_name):
        """
        INSERT
        INTO
        public.products(store_id, title, image, url)
        VALUES((SELECT id FROM stores WHERE store_name = 'footish'), 'Teva Flatform Universal Pride',
               'https://www.footish.se/sneakers/teva-flatform-universal-pride-t1116376',
               'https://www.footish.se/pub_images/large/teva-flatform-universal-pride-t1116376-p77148.jpg?timestamp=1623417840')
        """
        try:
            return cls.insert(
                store_id=cls.select(cls.store.id).join(Stores).where(cls.store.store_name == store_name).get().store.id,
                title=pageData.title,
                url=pageData.url,
                image=pageData.image,
            ).execute()
        except Products.DoesNotExist:
           return None

However I have realized that working with id's is quite faster than working with text and I have an issue where I am trying to figure out what would be the best way to insert the ID. I did get a comment regarding my code as for today:

your insert isn't' referencing "stores" at all so not sure what your hoping to get from that since you have a sub query there

I am a bit confused what that means however my question is that I would like to know which approach is the correct way to insert

  1. Is it better on start of application, to store the id as a variable and pass the variable into a insert function (argument)
  2. Or to call store_id=cls.select(cls.store.id).join(Stores).where(cls.store.store_name == store_name).get().store.id where I instead pass the store_name and then it would return the correct id?

My first thought is that by doing the number 2, that is like doing 2 queries instead of one? but I might be wrong. Looking forward to know!

1 Answers

This is quite incorrect:

# Wrong
store_id=cls.select(cls.store.id).join(Stores).where(cls.store.store_name == store_name).get().store.id,

Correct:

try:
    store = Stores.select().where(Stores.name == store_name).get()
except Stores.DoesNotExist:
    # the store name does not exist. do whatever?
    return
Products.insert(store=store, ...rest-of-fields...).execute()
Related