Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Postgresql - Insert into where not exists using sqlalchemy's INSERT from SELECT

As pointed out here its possible to do the following with postgresql 9.1+

INSERT INTO example_table
    (id, name)
SELECT 1, 'John'
WHERE
    NOT EXISTS (
        SELECT id FROM example_table WHERE id = 1
    );

I've been having a play around with version 0.9 of sqlalchemy where they have introduced INSERT from SELECT method which should theoretically handle the above.

Is it possible and if so how? (as i want to take advantage of the result.inserted_primary_key that is not returned when using raw sql)

How can I use bindparams for the 'from_select' part as the only way I can seem to use it is when using table columns in the select.

e.g.

insrt = example_table.insert().
    from_select(['id', 'name'],
    example_table.select().
    where(~exists(select([example_table.c.id],
    example_table.c.id == 1))))

result = session.execute(insrt)

if result.is_insert:
    print 'do something with result.inserted_primary_key'
like image 530
7wonders Avatar asked Aug 29 '13 02:08

7wonders


People also ask

How do you insert record if not exists PostgreSQL?

Firstly we have to mention the table name followed by column names (attributes) where we want to insert rows. Secondly, we must enter the values, separated by a comma after the VALUE clause. Finally, every value must be in the same order as the sequence of attribute lists is provided while creating a particular table.

How do I add multiple values in PostgreSQL?

First, specify the name of the table that you want to insert data after the INSERT INTO keywords. Second, list the required columns or all columns of the table in parentheses that follow the table name. Third, supply a comma-separated list of rows after the VALUES keyword.

What is needed for an insert on conflict update to work?

You must have INSERT privilege on a table in order to insert into it. If ON CONFLICT DO UPDATE is present, UPDATE privilege on the table is also required. If a column list is specified, you only need INSERT privilege on the listed columns.


1 Answers

from sqlalchemy import *

"""
INSERT INTO example_table
    (id, name)
SELECT 1, 'John'
WHERE
    NOT EXISTS (
        SELECT id FROM example_table WHERE id = 1
    );
"""

m = MetaData()

example_table = Table("example_table", m,
                        Column('id', Integer),
                        Column('name', String)
                    )

sel = select([literal("1"), literal("John")]).where(
           ~exists([example_table.c.id]).where(example_table.c.id == 1)
      )

ins = example_table.insert().from_select(["id", "name"], sel)
print(ins)

output:

INSERT INTO example_table (id, name) SELECT :param_1 AS anon_1, :param_2 AS anon_2 
WHERE NOT (EXISTS (SELECT example_table.id 
FROM example_table 
WHERE example_table.id = :id_1))
like image 116
zzzeek Avatar answered Sep 20 '22 14:09

zzzeek