Matthew
was the pony example using sqlite?
Alexander
Yes, by default it uses SQLite
Matthew
i can confirm double %% works
Alexander
Now you can use native modulo division for all databases we support.
select(x for x in X if x.id % 1337 == 0)
Alexander
Using GitHub version ofc.
Alexander
Will be included in the next release
Matthew
great :D
Valentin
Good. I need also string.strip :D
Matthew
For what use case?
Valentin
For stupid legacy database that store array like this "1 2 3"
Alexander
We already support strip method. Maybe you mean split
Valentin
Oh, yeah. My bad.
Valentin
It's not really a feature request as it's not really needed by everyone
Valentin
May be I'll do it myself someday.
Alexander
Ok. We can add it if you suggest how to translate it to SQL
Alexander
sqlite3.create_function() will translate any your wish
Alexander
Alexander
It is not as easy even for SQLite, because you need to return array of strings from this function
Matthew
Why not just do it in python?
Valentin
The problem is I need to search in them. I used to do "if number in ugly_string_array" it was enough... but... you know. There can be collisions the future.
Valentin
In python I would need to itterate trough quite big amount of record. But still I can itterate after using "in"... but it's as ugly as database structure itself :D
Alexander
You can search using LIKE operator if string components are separated properly.
class Article(db.Entity):
name = Required(str)
tags = Optional(str)
...
with db_session:
a1 = Article(name='Article1', tags='*foo*bar*baz*')
...
with db_session:
baz_articles = Article.select(lambda a: '*baz*' in a.tags)
Valentin
Hmm. Interesting.
@
hey guys. I'm new to PonyORM and SQL in general. I've been browsing the documentation, trying to decide between sqlalchemy and pony, and I noticed there is no apparent way to do database migrations (ie. /w Alembic). What is the best practice around this?
Lucky
@
cool. I'll play with that. Is there any ETA on official migration tool?
Lucky
Should be here already since quite some time, but It seems to be delayed.
Alexander
Yes. There are good reasons for that.
Alexander
I mean delay.
Lucky
Please elaborate
Alexander
Im not sure is that super secret inside info or not.
But we keep work on them.
Lucky
Uhhh. Seeeeeeeeecrets!
Alexander
Like: migrations that we have now is not that thing we really want to release.
@
what in your opinion is the hardest thing about migrations?
Alexander
In my - merge migration branches.
Lucky
Hah, merging branches always is fun
Matthew
pony.orm.core.OptimisticCheckError: Object User[x] was updated outside of current transaction
- would it be possible to expand this error message to show which attribute(s) were updated?
Matthew
then I can know which can be marked as optimistic
Alexander
It is not easy to do. If a program retrieves an object with specific id value, read attributes b, c and d and then update attributes a and b, Pony will send a query which looks like
UPDATE t1
SET a = <new_a>, b = <new_b>
WHERE id = <id> AND b = <prev_b> AND c = <prev_c> AND d = <prev_d>
And then Pony checks the number of rows which were updated. It may be 1 or 0. Zero means that some attribute where changed, but it is hard to say which exactly.
Maybe in this case we can do additional select in order to retrieve new attribute values
Alexander
I'm not sure that marking attribute as not optimistic is correct solution, because this way you just hide some lost update
Matthew
In this case, I am not editing the object apart from a single attribute, a "date" type, is there a way to ignore all of the other attributes changing?
Matthew
this is a very CPU intensive task, so redoing it isn't ideal
Matthew
Maybe catching the OptimisticCheckError, then retrying that single attribute update?
Matthew
I don't think I want to lock the object, as this would stop users from doing other things during the multiple minute background processing job
Alexander
Maybe we can add new option to db_session, something like:
with db_session(optimistic=False):
...
Alexander
This option will turn off optimistic checks. It may lead to lost updates, so programmer need to be careful about when to use it
Matthew
That sounds like it could work, but maybe I'm missing something and Pony already allows this?
Matthew
I don't think restarting the whole transaction makes sense
Matthew
the use case is doing a lot of reads from the database, writing some computed data to redis as a cache, then marking that user object as computed for today
Matthew
Since the modulus now works, there are multiple processes doing this, so there are a lot more optimistic errors
Alexander
I think you can attempt the following:
1) Mark that single datetime attribute as volatile. It is possible that you have concurrent processes that tries to do the same calculation on the same object in parallel.
You can also add some in_process volatile flag to object which will prevent concurrent processes to start the same calculation for object that is already processing.
2) If concurrent processes actually changes some attributes beside that single datetime attribute, then I'm not sure your redis cache contains valid non-obsolete data. It looks suspicious to me.
But if you think that all is OK, you can prevent optimistic errors by extracting that single datetime attribute to another object. Then you entities may look like:
class MyObject(db.Entity):
id = PrimaryKey(int, auto=True)
foo = Required(int)
bar = Optional(str)
object_state = Optional(lambda: ObjectState)
class ObjectState(db.Entity):
id = PrimaryKey(int, auto=True)
object = Required(MyObject, unique=True)
in_process = Required(bool, default=False)
processed_at = Optional(datetime)
Then, you should create objects in pairs:
obj = MyObject(foo=10, bar='hello')
obj_state = ObjectState(object=obj)
And then you can process object as following:
with db_session:
query = MyObject.select(lambda obj: obj.id % N == M)
query = query.filter(obj.foo == X)
query = query.filter(lambda obj:
not obj.object_state.in_process and (
obj.processed_at is None or
obj.processed_at < datetime.now() - timedelta(days=1)))
objects_to_process = query[:]
for obj in objects_to_process:
obj.object_state.in_process = True
commit()
for obj in object_to_process:
make_some_complex_caclulation(obj)
obj.object_state.in_process = False
obj.object_state.processed_at = datetime.now()
In that case, you read foo and bar attributes from obj and write in_process and processed_at attributes to obj_state, so concurrent errors should not appear
Alexander
But in any case I need to do the following:
1) Change Pony code so if you start db_session with serializable=True option (which means full isolation) than optimistic checks are not added to queries.
2) In case of optimistic errors, make additional query to database in order to determine which attribute was changed
Anonymous
./
Alexander
Hola.
Matthew
Has anyone tried pony with the postgres 10 betas yet? I plan on doing so soon and wanted to know if there are any problems
Lucky
Matthew
Parallel queries is the big advantage I see
Matthew
https://news.ycombinator.com/item?id=15306398
Lucky
/translate
Lucky
@akozlovsky can I add @bonbot for the /translate command and for the github permalinks?
Lucky
Ah, ok xD
Point still stays xD
Alexander
Alexander
Any docs of usage?
Святослав
/translate@bonbot
stsouko
/help@bonbot
Micaiah
Anyone have issues with pony and gunicorn?
Micaiah
My app is failing if I import my models (which includes binding to the database)
Alexander
With what exception?
Micaiah
Nevermind, it was a dumb syntax error :/
Joery
Hi
Joery
is this supposed to happen?
Vitalii
definitely not, please give a link to your diagram
Joery
https://editor.ponyorm.com/user/joery/test/designer
Joery
I always happens, after you add the first entity
Vitalii
it is fixed now
Joery
Awesome! Thank you
Joery
I also have another question, the 'Table name' input is automatically capitalized. Is it supposed to be like that?