Jaymon / prom

A PostgreSQL or SQLite orm for Python
MIT License
22 stars 4 forks source link

Cleanup Query api #24

Closed Jaymon closed 2 years ago

Jaymon commented 8 years ago

I would like to explore the following interface:

1) if you add select fields then get() or all() would return just the selected fields, not Orm instances. Likewise, if you called get_one() it would return just the value, not an orm instance, basically, we never want half populated orm objects for it to be the default, so if you did want a half populated orm object you could just create it and pass in the values returned. We almost exclusively want lists when we use the select() method.

2) change get_one() to one() so that it is more inline with first() and last(), I know why I did this, to make it similar to get() and get_pk().

3) remove Query value() and values(), because of number 1 above, we wouldn't need these any longer, and if you ever needed them with the full fields, they would still exist on the returned iterator.

Jaymon commented 4 years ago

I'd like to shorten all the *_field methods to just the * part (eg, eq_field would become eq) so you could do things like...

Foo.query.eq("bar", "<VALUE>")

instead of...

Foo.query.eq_field("bar", "<VALUE>")

Sadly, in is holding me back. I wanted to support all the Query and Projection Operators:

And they all work except in (if I switch is to eq which I'm fine with). Sadly, I can't think of any other method that would work for in, I thought about any, and have even thought about inn or _in or in_ but it would be strange to have just in be different. So I think I'll keep *_field.

Jaymon commented 4 years ago

For other ideas on how to clean up Query I could use Mongo's Query Documents tutorial

Jaymon commented 4 years ago

Some ideas:

Orm.query.eq_("bar", 1).in_("che", [1, 2, 3])
Orm.query._eq("bar", 1)._in("che", [1, 2, 3])
Orm.query.eq_field("bar", 1).in_field("che", [1, 2, 3])

q = Orm.query
q.bar.eq(1)
q.che.in([1, 2, 3])
Jaymon commented 3 years ago

What if I use all capital letters?

Orm.query.EQ("bar", 1).IN("foo", [1, 2, 3, 4])
Jaymon commented 2 years ago

I so rarely use the *_field syntax that I don't think it's worth keeping this open anymore, all the items in the original writeup have been addressed

Jaymon commented 1 year ago

From PEP8 (via):

  • _single_leading_underscore - weak "internal use" indicator. E.g. from M import * does not import objects whose name starts with an underscore.
  • single_trailing_underscore_ - used by convention to avoid conflicts with Python keyword, e.g. Tkinter.Toplevel(master, class_='ClassName')
  • __double_leading_underscore - when naming a class attribute, invokes name mangling (inside class FooBar, __boo becomes _FooBar__boo; see below).
  • __double_leading_and_trailing_underscore__ - "magic" objects or attributes that live in user-controlled namespaces. E.g. __init__, __import__ or __file__. Never invent such names; only use them as documented.

So the best way to handle or and in collisions would be to use or_ and in_