On Thu, Nov 26, 2020, at 5:05 PM, Kata Char wrote:
> Is the documentation up-to-date?

yup

> 
> 
> 
> I printed out a query and there were two insert statements, but the 
> documentation shows one - am I doing something wrong?
> I see in the postgresql logs two insert statements
> LOG:  statement: INSERT INTO foo (test) VALUES ('foo1')

> 

> LOG:  statement: INSERT INTO foo (test) VALUES ('foo2')


that's what PostgreSQL drivers do by default when you use executemany().   See  
<https://www.psycopg.org/docs/cursor.html#cursor.executemany> 
<https://www.psycopg.org/docs/cursor.html#cursor.executemany> 
<https://www.psycopg.org/docs/cursor.html#cursor.executemany> 
<https://www.psycopg.org/docs/cursor.html#cursor.executemany> 
<https://www.psycopg.org/docs/cursor.html#cursor.executemany>https://www.psycopg.org/docs/cursor.html#cursor.executemany
  for a description of how this works.   the psycopg2 driver also binds values 
into the SQL statement directly when it passes to the DB so that's why you see 
parameters rendered.   The "loop" that it runs is *slightly* faster than doing 
it in pure Python as psycopg2 is written in C, however, it's widely known that 
psycopg2's executemany() implementation is very slow.  

That's why as you'll note in the docs for it, it recommends the use of "fast 
execution helpers", which can be used to pass the INSERT statement(s) in two 
different ways, either as many INSERT statements together with a semicolon or 
as a single INSERT with VALUES.  You're looking for the latter.    SQLAlchemy 
supports these modes as documented at  
<https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2-executemany-mode>
 
<https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2-executemany-mode>https://docs.sqlalchemy.org/en/13/dialects/postgresql.html#psycopg2-executemany-mode,
 which in version 1.3 have to be opted-into using create_engine options.  
However, in version 1.4, a better set of modes are added and the default 
behavior now defaults to the fastest form for INSERT.. VALUES as documented at 
https://docs.sqlalchemy.org/en/14/dialects/postgresql.html#psycopg2-executemany-mode.
 

Short answer, use 1.4.0b1 or set the appropriate flags with 1.3 with psycopg2.  
 The two other drivers we support, pg8000 and asyncpg, both use prepared 
statements, so the entire mechanism by which these parameters are passed is 
different and they should perform better than default psycopg2 at the level of 
how the statement is passed to the database (although pg8000 overall performs 
more slowly than both because it's not written in C).


> This happens for other variants like table(...), bulk_insert_mappings, etc. 
> According to the documentation, it should be something like `INSERT INTO foo 
> (test) VALUES (?) (('foo1'), ('foo2'))`


That documentation indicates 1. the SQL statement and then 2. the individual 
parameters being passed in a list to a single call to cursor.executemany().    
The DBAPI should be responsible for optimizing this but unfortunately the 
psycopg2 driver does not optimize it well since it does not use prepared 
statements, SQLAlchemy has to make use of a more awkward API to make it work 
(and this API is used much more effectively in 1.4.0).





> 
> On Wednesday, November 25, 2020 at 2:34:36 PM UTC-8 Mike Bayer wrote:
>> __
>> technically Table and TableClause are a little bit different but I don't 
>> think there's any behavioral difference at the level of 
>> execute(obj.insert()).   what matters more is if the Column objects have 
>> datatypes or defaults that incur some kind of Python-side processing or not.
>> 
>> On Wed, Nov 25, 2020, at 4:33 PM, 'Jonathan Vanasco' via sqlalchemy wrote:
>>> This was not clear enough in Mike's post: `Foo.__table__` is the same type 
>>> of object as `_foo = table(...)`.  SQLAlchemy ORM is built on top of 
>>> SQLAlchemy's Core, so the  ORM's `.__table__` attribute is the Core's 
>>> `table()` object.
>>> 
>>> Since they're the same, the two will have the same performance within 
>>> `conn.execute(`.
>>> 
>>> On Wednesday, November 25, 2020 at 4:18:46 PM UTC-5 Kata Char wrote:
>>>> I see, does that mean there is no difference in performance if one or the 
>>>> other is used? In other words
>>>>     from sqlalchemy.sql import table
>>>> 
>>>>     _foo = table(...)
>>>>     conn.execute(_foo.insert(), [{...}, ...])
>>>> 
>>>> Would have the same performance as `conn.execute(Foo.__table__.insert(), 
>>>> [{...}, ...])`
>>>> 
>>>> On Wednesday, November 25, 2020 at 8:27:53 AM UTC-8 Mike Bayer wrote:
>>>>> 
>>>>> 
>>>>> On Wed, Nov 25, 2020, at 10:30 AM, Kata Char wrote:
>>>>>> Hi, sorry if this post is a duplicate, my first one didn't seem to make 
>>>>>> it.
>>>>>> 
>>>>>> I was reading the documentation:
>>>>>> - https://docs.sqlalchemy.org/en/13/core/tutorial.html#execute-multiple
>>>>>> 
>>>>>> - 
>>>>>> https://docs.sqlalchemy.org/en/13/_modules/examples/performance/bulk_inserts.html
>>>>>> 
>>>>>> Is there any difference between conn.execute(TableClause.insert(), 
>>>>>> [...]) vs conn.execute(Model.__table__.insert(), [...])?
>>>>>> 
>>>>>> The first one is documented to use execumany(), but what about the 
>>>>>> second one? 
>>>>> 
>>>>> Any conn.execute() that passes a list of dictionaries as the second 
>>>>> argument, where there is more than one entry in the list, will use the 
>>>>> executemany() style with the DBAPI connection.
>>>>> 
>>>>> With the ORM the Model.__table__ attribute is a Table object.  That 
>>>>> tutorial seems to be referencing TableClause which is the base class for 
>>>>> Table, but all the examples there are using Table objects.
>>>>> 
>>>>> 
>>>>>> 

>>>>>> -- 
>>>>>> SQLAlchemy - 
>>>>>> The Python SQL Toolkit and Object Relational Mapper
>>>>>>  
>>>>>> http://www.sqlalchemy.org/
>>>>>>  
>>>>>> To post example code, please provide an MCVE: Minimal, Complete, and 
>>>>>> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
>>>>>> description.
>>>>>> --- 
>>>>>> You received this message because you are subscribed to the Google 
>>>>>> Groups "sqlalchemy" group.
>>>>>> To unsubscribe from this group and stop receiving emails from it, send 
>>>>>> an email to sqlalchemy+...@googlegroups.com.
>>>>>> To view this discussion on the web visit 
>>>>>> https://groups.google.com/d/msgid/sqlalchemy/1ffe48c6-4124-40ab-902f-ffa86885ea94n%40googlegroups.com
>>>>>>  
>>>>>> <https://groups.google.com/d/msgid/sqlalchemy/1ffe48c6-4124-40ab-902f-ffa86885ea94n%40googlegroups.com?utm_medium=email&utm_source=footer>.
>>>>> 
>>> 

>>> -- 
>>> SQLAlchemy - 
>>> The Python SQL Toolkit and Object Relational Mapper
>>>  
>>> http://www.sqlalchemy.org/
>>>  
>>> To post example code, please provide an MCVE: Minimal, Complete, and 
>>> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
>>> description.
>>> --- 
>>> You received this message because you are subscribed to the Google Groups 
>>> "sqlalchemy" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an 
>>> email to sqlalchemy+...@googlegroups.com.
>>> To view this discussion on the web visit 
>>> https://groups.google.com/d/msgid/sqlalchemy/89002280-96e7-45e9-a11a-f104d8e2aa3fn%40googlegroups.com
>>>  
>>> <https://groups.google.com/d/msgid/sqlalchemy/89002280-96e7-45e9-a11a-f104d8e2aa3fn%40googlegroups.com?utm_medium=email&utm_source=footer>.
>> 
> 

> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/9dbd9e55-96b5-4d28-8561-0da19ab815dbn%40googlegroups.com
>  
> <https://groups.google.com/d/msgid/sqlalchemy/9dbd9e55-96b5-4d28-8561-0da19ab815dbn%40googlegroups.com?utm_medium=email&utm_source=footer>.

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/7a31ba2f-b435-474e-b0f9-906e7afb6de6%40www.fastmail.com.

Reply via email to