Pg8000 – Pure-Python PostgreSQL driver
github.com
github.com
* All statements start a transaction automatically if one isn't already open.
* You need to call .commit() or .rollback() on the connection object to do the commit or rollback.
* The driver can optionally support an "autocommit mode" where, instead of the above rules, every individual statement is wrapped in its own transaction and committed immediately.
That's the theory. Many database drivers, including the built-in SQLite driver, differ in practice (for example, it doesn't automatically start a transaction for a SELECT statement).
The biggest common practical difference is an implementation detail of so-called "autocommit mode". Often that is NOT implemented by actually issuing a "BEGIN TRANSACTION" before and "COMMIT" after every statement. Instead, it often just issues the statement without any automatic transaction statements whatsoever, relying on the fact that the underlying database engine will immediately commit any statements outside an explicit transaction (i.e. has its own autocommit mode).
That means if you do want complete manual control of transactions in a Python DB-API driver (including sqlite), then - confusingly - you need to set the autocommit option to true!
It's not clear to me whether/how this applies to pg8000 driver in the OP. There is a section on autocommit but it doesn't explicitly say what it does.
The native API is a lot simpler, and so I'd use that if you can. The native API is really my suggestion for the next version of DB-API, so DB-API 3. I'd be interested to know people's thoughts on this, and maybe we could put together a draft specification?
Unless one's interaction with the database are really basic (i.e. a single SELECT statement), one would want to be as explicit as possible regarding where transaction boundaries are.
Having a default that hides this aspect from my code always seemed a false convenience to me.
edit: this is just a tangential reflection inspired by your comment, not an answer / nor I wanted to detract from your fact statement.
If your writes are single table and don't require transactional safety, why introduce transactions?
If you need complex, multiple-insert or update writes, transactions are great, but that can also be accomplished in a stored proc.
In a high-velocity environment, avoiding transactions are a great way to get more throughput out of your database server with lower latencies.
Combine Postgres with pgBouncer in statement mode and you can scale it pretty dramatically.
AFAIK autocommit mode just applies if you don't explicitly open a transaction, so what would you propose instead? That a transaction is silently opened but not committed (potentially leaving a dangling transaction open for a long time after SELECT statement) (like Python's odd default behaviour)? Or an immediate error?
I can certainly see that if you are indeed wrapping every individual statement in their own BEGIN/COMMIT pairs that you'd wonder why the database can't help you for such simple use cases. You can still selectively open an explicit transaction on those statements that do need to be grouped together, so I don't see that you've given up any control.
Databases that only do the technically-correct thing are weeded out because they lose the big supportive cloud of novices that experts grow out of. So the good databases support the intuitive way and the the correct way of manipulating data.
There are more computing concepts to learn than there are hours to learn it in. People use systems they don't understand and systems need to support that.
Haven't had any issues since!
"The binary package is a practical choice for development and testing but in production it is advised to use the package built from sources."
...or use one from your operating system distribution.
this guy has put one together though; might see if we can get it migrated into the original version.
https://github.com/realazthat/aiopg8000/blob/master/aiopg800...
Did you mean postgresql's dollar literals?
- Simplifies and improves the performance of deployment: it becomes a straightforward case of copying code files
- Largely achieves the same stated goal of Java: write once, run anywhere
- Allows for easy code inspection and debugging in production (it's debatable whether that's a good thing; I think it is, overall)
Take all benchmarking with a pinch of salt, but see some stats here: https://suade.org/dev/12-requests-per-second-with-python/#th...
The pure python MySQL drivers were marginally slower for cpython.
The native drivers worked fine with pypy, but pypy didn’t give any real performance gains as the program spent all its time in the native code
Then when testing pure python drivers we found pypy made the whole program massively faster.
The programs were ETLs that are generating big REPLACE INTO statements.
Different databases and drivers do prepared statements in different ways. Postgres, for example, can receive the statement and the parameters and do the interpolation in the server. The params still need to be serial used by the client and the template isn’t reused, so it’s no big perf win.
MySQL, on the other hand, needs the driver to do the interpolation. The server only knows how to execute sql strings.
It turns out it is far better to prepare the sql in pure python where pypy knows all about types etc than to have the c MySQL driver do it.
Exactly the same thing plays out in java. The MySQL java drivers are staggeringly inefficient at large prepared statements, and in my profiling massive amounts of time is spent in java functions in the MySQL driver that are trying to work out where the next question-mark is. Sadly the drivers are the poo they are. Iirc the mariadb java drivers are rather more optimized.
I would argue a speedup (though maybe not a “massive” one) from pure python over a native extension is not that surprising, specifically because of (2), which makes it possible for the runtime-extension interface overhead to be more significant than (1). Native extensions tend to give a speed boost for computationally intensive tasks, but can’t really wait any faster, and aren’t free of overhead.