Giter VIP home page Giter VIP logo

Comments (5)

chadwhitacre avatar chadwhitacre commented on July 17, 2024

Ugh, we've also got strict_one to deal with, and since the docs are autogenerated, we can't easily change that in code without mucking up the docs. :-/

Should we just change 1.0.0? :-(

from postgres.py.

chadwhitacre avatar chadwhitacre commented on July 17, 2024

I think we should. :-(

from postgres.py.

chadwhitacre avatar chadwhitacre commented on July 17, 2024

Now I'm worried about row and rows being too similar, introducing bugs where you thought you were calling one but were calling the other.

for row in db.row("SELECT * FROM foo"):
   print(row)

vs.

for row in db.rows("SELECT * FROM foo"):
   print(row)

vs.

for row in db.one("SELECT * FROM foo"):
   print(row)

vs.

for row in db.many("SELECT * FROM foo"):
   print(row)

vs.

for row in db.one("SELECT * FROM foo"):
   print(row)

vs.

for row in db.rows("SELECT * FROM foo"):
   print(row)

Perhaps the cognitive obstacle between one and rows is good, because it helps you not confuse them.

I've already confused one and run. I did:

db.one("CREATE TABLE foo (bar text)")

Now that we have strict checking on one this raises postgres.TooFew: Got -1 rows instead of 1. Otherwise you get psycopg2.ProgrammingError: no results to fetch. (Hmmm ... makes me think maybe we should wrap one calls in a transaction and only commit them if there's exactly one row, because the table is still created here. Reticketed as #17.)

The confusion between one and run fails early and hard, when it fails:

  • If you call one when you meant to call run:
    • The query doesn't return one row and you get an exception (assuming you're using strict one checking—perhaps a good reason to).
    • The query does return one row and you have simply discarded it: not a problem.
  • If you call run when you meant to call one then you get None back, which if you are using strict one checking will be a surprise—another good reason to use that. Since you'd otherwise be expecting a dict (assuming you're using the default of RealDictCursor) then the failure would probably manifest as TypeError: 'NoneType' object is not subscriptable when you tried to do row['foo'].

By contrast if you were to call row when you meant rows you would get a dict that you could still iterate over. The bug would then manifest when you tried to treat one of the scalar dict values like a dict. If you call rows when you meant row then you'd get a list where you expect a dict and you'd probably see TypeError: list indices must be integers, not str.

In other words, strict one checking makes it less harmful to confuse one and run than it is to confuse one and rows. Should we rename rows to many? That feels too ORM-y to me. For me it invokes many-to-many relationships and relational algebra, which is decidedly not what we're modeling in Python here. rows is much more matter-of-fact, and fits better with the common case where you do:

for row in db.rows(SELECT, params):
    print(row)

But geez, this whole thing started this morning because I found myself wanting to say run / one / many. I don't like all there because my vim mis-highlights it as a builtin. :-/ It's also three letters instead of four which makes it easier to confuse with one (as well as run, I suppose). many fits fine semantically and it's longer than one so that's a subtle hint.

for row in db.many(SELECT, params):
    print(row)

I don't want to get into a holy war over ORMs so I shouldn't care about that factor. The question is what's going to be the most obvious API here and while there's probably not a "right" answer there's righter answers than others. I know it's annoying in CSS that it's vertical-align and text-align ... why isn't it horizontal-align? It should be parallel. If the goal is not to confuse them then one and many are certainly better than row and rows. Also, since we don't have to worry about the strict_one problem then we could simply alias rows = many and call it a day. I'm slightly annoyed that many could return zero or one result, which technically aren't many. I guess I can tell myself that it's an announcement of willingness to receive: "I'm willing to receive one result. I'm willing to receive many results." Meh. Don't like it. It could also return 10 out of 100 possible rows and still be many when we really want all rows, guaranteed. all really fits better semantically, but three characters, too similar. The vim thing can't be a reason.

Has this cave pinched out yet?

from postgres.py.

chadwhitacre avatar chadwhitacre commented on July 17, 2024

Reopened for @tshepang.

We could use all with a simple alias. We do advertise as being "an abstraction over psycopg2" so maintaining the association with DB-API 2.0 is relevant.

from postgres.py.

tshepang avatar tshepang commented on July 17, 2024

Sorry, it was a busy day here at work, so I didn't get a chance to visit this site, but I am quite satisfied with the choice you made... one / all. I am also glad that you took the time to write such detailed thoughts.

from postgres.py.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.