I use SQLAlchemy and there are at least three entities: engine, session and connection, which have execute method, so if
Nabeel's answer covers a lot of details and is helpful, but I found it confusing to follow. Since this is currently the first Google result for this issue, adding my understanding of it for future people that find this question:
As OP and Nabell Ahmed both note, when executing a plain SELECT * FROM tablename, there's no difference in the result provided.
The differences between these three objects do become important depending on the context that the SELECT statement is used in or, more commonly, when you want to do other things like INSERT, DELETE, etc.
Engine is the lowest level object used by SQLAlchemy. It maintains a pool of connections available for use whenever the application needs to talk to the database. .execute() is a convenience method that first calls conn = engine.connect(close_with_result=True) and the then conn.execute(). The close_with_result parameter means the connection is closed automatically. (I'm slightly paraphrasing the source code, but essentially true). edit: Here's the source code for engine.execute
You can use engine to execute raw SQL.
result = engine.execute('SELECT * FROM tablename;')
#what engine.execute() is doing under the hood
conn = engine.connect(close_with_result=True)
result = conn.execute('SELECT * FROM tablename;')
#after you iterate over the results, the result and connection get closed
for row in result:
print(result['columnname']
#or you can explicitly close the result, which also closes the connection
result.close()
This is covered in the docs under basic usage.
Connection is (as we saw above) the thing that actually does the work of executing a SQL query. You should do this whenever you want greater control over attributes of the connection, when it gets closed, etc. For example, a very import example of this is a Transaction, which lets you decide when to commit your changes to the database. In normal use, changes are autocommitted. With the use of transactions, you could (for example) run several different SQL statements and if something goes wrong with one of them you could undo all the changes at once.
connection = engine.connect()
trans = connection.begin()
try:
connection.execute("INSERT INTO films VALUES ('Comedy', '82 minutes');")
connection.execute("INSERT INTO datalog VALUES ('added a comedy');")
trans.commit()
except:
trans.rollback()
raise
This would let you undo both changes if one failed, like if you forgot to create the datalog table.
So if you're executing raw SQL code and need control, use connections
Sessions are used for the Object Relationship Management (ORM) aspect of SQLAlchemy (in fact you can see this from how they're imported: from sqlalchemy.orm import sessionmaker). They use connections and transactions under the hood to run their automatically-generated SQL statements. .execute() is a convenience function that passes through to whatever the session is bound to (usually an engine, but can be a connection).
If you're using the ORM functionality, use session; if you're only doing straight SQL queries not bound to objects, you're probably better off using connections directly.