Lucky
Lucky
Would love to contribute
Alexander
Sure, we can discuss. I'll be pretty busy onboarding a new job this week, but I should have time from September 24th (next Tuesday). We can connect starting this date.
Alexander
Hi everyone, is there any news about the support of Python 3.13?
And about the support of "is" in selects, like
db.Something.select(lambda x: x.some_field is None)
Alexander
Hi!
It all depends on how many changes in a bytecode new version has.
We havent look at it yet
Ames
How to implement logical deletion in Pony ORM?
Ames
like in any another ORM, make is_delete bool field
How should I modify the entity's delete method to update the logical deletion field?
Alexander
In general you do this in an application/service logic side.
For example on DELETE /{item_id} you implement this not DELETE but UPDATE
aldo
on pony 1.0.2, python 3.10.14
Alexander
Sadly newest version of Pony is 0.7.19
Isn't this link a virus?
Alexander
Alexander
Justin
Ah okay. I saw a post on the github page for pony, but the ORM doesn't appear to allow db execution without it being in a transaction. This didn't seem to work https://github.com/ponyorm/pony/issues/329
aldo
good morning, i've defined a column like foo = orm.Optional(orm.Json), but when looking at the .db file (sqlite) it shows foo JSON NOT NULL as the column definition
was expecting that it would allow NULL, as it was declared as Optional
if that is not convenient, then perhaps should provide a sane default: JSON NOT NULL DEFAULT {}
this would easy migrations with external tools
Alexander
Hello, also as fot strings pony prefers using empty values instead of nulls.
aldo
Hello, also as fot strings pony prefers using empty values instead of nulls.
sorry, ¿what's a fot string?
Alexander
Optional strings are not nullable columns
Amo
Hi, here and there it is recommended to not use auto increment as ID because it exposes information about the items. Is there anything builtin pony (except for uuid) that solves this?
Alexander
Hello. You can use any type of primary key that db allows.
There is nothing actually "to solve"
Amo
Yes, so pony does not bring any mechanism to create a more randomized id? I have the feeling, if I create it myself I also have to manage collisions. So I Need a try catch for each insert
Alexander
uuid is pretty good solution overall
Amo
Amo
uuid is pretty good solution overall
AFAIK there is a performance impact. Though that's something I have to measure and decide if it's critical
Alexander
UUID potentially has a large performance impact when it is used as a primary key, as a secondary key it should be fine
Alexander
I don't believe this is noticeable nowadays
Amo
Thanks for your opinion on this topic and happy Christmas to you two :)
aldo
good morning. have several models that map to different tables, now they want to add some common attributes like: is_deleted, {created,modified,deleted}_at and comment.
can't use inheritance as it will end with only one table, ¿any ideas?
ps: happy new year
Alexander
Hello, you can use inheritance in Pony.
But for this case base entity would be too "meta" and it would end with really wide table.
aldo
indeed. also there would be too many rows
Alexander
Hello, guys! Is there any news about the support of Python 3.12?
Alexander
Denis
mariadb --version
mariadb from 11.4.3-MariaDB, client 15.2 for debian-linux-gnu (x86_64) using EditLine wrapper
Alexander
I belive that might happen because pony doesnt support mariadb. It supports mysql but probably their syntax is different in some cases now
Denis
I resolved it by istalling it:
violation = Optional(Json, nullable=True)
By default Pony writes {} as an empty value and it cannot be overwritten, but NULL can be overwritten
Santosh
Any update on python 3.13 support
Santosh
Does current version of python works with 3.13?
Alexander
It doesnt
Mike
Hey everyone! I am having some weirdness with manipulating an entity that was created with a different transaction.
Here is the python code I am using to test
from datetime import datetime
from pony import orm
from pony.orm import Required, db_session, Set
db = orm.Database()
class Foo(db.Entity):
insert_time = Required( datetime, default = datetime.now())
key = Required(str)
value = Required(str)
bar = Set('Bar', reverse = "foo")
class Bar(db.Entity):
key = Required(str)
value =Required(str)
foo = Set('Foo', reverse="bar")
def add_to_foo(self, key, value):
if Foo.get(key = key):
print(f"{key} already exists in foo!")
return
Foo(key = key, value = value)
db.bind(provider = 'sqlite', filename = ':memory:')
db.generate_mapping(create_tables=True, check_tables=True)
# Simulates manipulating related objects with different transaction
with db_session:
f = Foo(key = "hello", value = "world")
with db_session:
b = Bar(key = "msg1", value = 'msg2', foo = f)
with db_session:
b.add_to_foo("msg3", "this is important!")
This tosses the following error
Traceback (most recent call last):
File "/home/miversen/git/spotify-playlist-exporter/test.py", line 31, in <module>
b = Bar(key = "msg1", value = 'msg2', foo = f)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/miversen/git/spotify-playlist-exporter/.venv/lib/python3.12/site-packages/pony/orm/core.py", line 4706, in __init__
avdict[attr] = attr.validate(val, obj, from_db=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/miversen/git/spotify-playlist-exporter/.venv/lib/python3.12/site-packages/pony/orm/core.py", line 2827, in validate
throw(TransactionError, 'An attempt to mix objects belonging to different transactions')
File "/home/miversen/git/spotify-playlist-exporter/.venv/lib/python3.12/site-packages/pony/utils/utils.py", line 99, in throw
raise exc
pony.orm.core.TransactionError: An attempt to mix objects belonging to different transactions
I'm not really sure how to proceed here. This is of course a boiled down version of what I was actually doing when I encountered the error but any guidance would be great
Alexander
Hey everyone! I am having some weirdness with manipulating an entity that was created with a different transaction.
Here is the python code I am using to test
from datetime import datetime
from pony import orm
from pony.orm import Required, db_session, Set
db = orm.Database()
class Foo(db.Entity):
insert_time = Required( datetime, default = datetime.now())
key = Required(str)
value = Required(str)
bar = Set('Bar', reverse = "foo")
class Bar(db.Entity):
key = Required(str)
value =Required(str)
foo = Set('Foo', reverse="bar")
def add_to_foo(self, key, value):
if Foo.get(key = key):
print(f"{key} already exists in foo!")
return
Foo(key = key, value = value)
db.bind(provider = 'sqlite', filename = ':memory:')
db.generate_mapping(create_tables=True, check_tables=True)
# Simulates manipulating related objects with different transaction
with db_session:
f = Foo(key = "hello", value = "world")
with db_session:
b = Bar(key = "msg1", value = 'msg2', foo = f)
with db_session:
b.add_to_foo("msg3", "this is important!")
This tosses the following error
Traceback (most recent call last):
File "/home/miversen/git/spotify-playlist-exporter/test.py", line 31, in <module>
b = Bar(key = "msg1", value = 'msg2', foo = f)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/miversen/git/spotify-playlist-exporter/.venv/lib/python3.12/site-packages/pony/orm/core.py", line 4706, in __init__
avdict[attr] = attr.validate(val, obj, from_db=False)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/home/miversen/git/spotify-playlist-exporter/.venv/lib/python3.12/site-packages/pony/orm/core.py", line 2827, in validate
throw(TransactionError, 'An attempt to mix objects belonging to different transactions')
File "/home/miversen/git/spotify-playlist-exporter/.venv/lib/python3.12/site-packages/pony/utils/utils.py", line 99, in throw
raise exc
pony.orm.core.TransactionError: An attempt to mix objects belonging to different transactions
I'm not really sure how to proceed here. This is of course a boiled down version of what I was actually doing when I encountered the error but any guidance would be great
Why don't you use one session for these 3 operations with DB?
Mike
The example above is a highly boiled down version of the problem. I _can_ use one session for everything but then if anything happens during that session, all transactions are rolled back and lost
Mike
Which is exactly what happened and how I ended up here trying to figure out the "correct" way to do this lol
Alexander
Mike
How so? If I have an insert (for example) that is completely fine, but there is a completely unrelated issue down the road, why would it be ok for that insert to be rolled back?
Mike
Encapsulating everything in one transaction feels very wrong
Alexander
How so? If I have an insert (for example) that is completely fine, but there is a completely unrelated issue down the road, why would it be ok for that insert to be rolled back?
When you close the session, you can assume that this object is already read-only. If you need to make changes to it, you will have to find this object again in the new session and then change it.
with db_session:
f = Foo(key = "hello", value = "world")
b = Bar(key = "msg1", value = 'msg2', foo = f)
b.add_to_foo("msg3", "this is important!")
looks fine for me
Mike
That makes sense, but it counters my understanding of how pony works.
I have revised the above code to better reflect what I am actually seeing
from pony import orm
from pony.orm import Required, db_session, Set
db = orm.Database()
class Foo(db.Entity):
key = Required(str)
value = Required(str)
bar = Set('Bar', reverse = "foo")
class Bar(db.Entity):
key = Required(str)
value =Required(str)
foo = Set('Foo', reverse="bar")
def add_to_foo(self, key, value):
if Foo.get(key = key):
print(f"{key} already exists in foo!")
return
Foo(key = key, value = value)
db.bind(provider = 'sqlite', filename = ':memory:')
db.generate_mapping(create_tables=True, check_tables=True)
@db_session
def create_foo() -> Foo:
return Foo(key = "hello", value = "world")
@db_session
def create_bar(foo: Foo) -> Bar:
return Bar(key = "msg1", value = "msg2", foo = foo)
@db_session
def add_item_to_foo(bar: Bar):
bar.add_to_foo(key = "msg3", value = "this is important!")
foo = create_foo()
bar = create_bar(foo)
# ... Do all kinds of other completely unrelated tasks
add_item_to_foo(bar)
Mike
If _anything_ fails in "do all kinds of other completely unrelated tasks", foo and bar are lost as they never got written to memory
Mike
*the database.
Alexander
You can use commit() if you need to save something inside a session, BTW.
Mike
I understand that. I just don't understand why I should have to wrap my entire program under one session. That is not how the documentation reads.
Alexander
Mike
I feel like that is what I am trying to do with the above code?
Mike
I am opening a session for each of the methods that manipulate the database.
But I get the exception
pony.orm.core.TransactionError: An attempt to mix objects belonging to different transactions
Mike
I suppose my issue is that I don't know what I am doing wrong here.
https://docs.ponyorm.org/firststeps.html#db-session
Comparing what I have to the documentation, it _seems_ like I am doing it correctly but I am getting different results. The error is clear that I am doing something wrong but I don't know how to make it not wrong
Alexander
Alexander
something like
@db_session
def add_item_to_foo(bar: Bar):
bar = Bar.get(id=bar.id)
bar.add_to_foo(key = "msg3", value = "this is important!")
Mike
Ohhhhh
Mike
That makes sense, I suppose I was misunderstanding what you said earlier.
So I can't treat entities quite the same as other python objects due to how transactions work?
Alexander
After the session is closed, you cannot change this object so that the changes are recorded in the database.
Mike
I'm tracking now. I may be back, lemme go make some changes in my code and see if I can grok through how to correctly do that
Mike
That made it work :) I also opened an issue on the repo, I am going to summarize our convo there and close the issue out
Mike
Thank you so much @supershurik !
Santosh
@metaprogrammer any plans to support python 3.13 in near future ?
Madd
Any one know about convert natural language into sql query useing pony ORM
Artemiy
There is no such thing as natural language processing in ORM.
You should take either a parsing route, or an AI route.
For parsing, Pony is quite handy for actually constructing queries.
For AI...
Pony can execute raw SQL queries, and you can get schema from object definitions.
If you use capable LLM, it will know Pony and can produce Python code, which is easier to review. (For safety, you should really review any mutating code from LLM, it almost as dangerous as UGC)
aldo
good morning, I need to read a sqlite db that has this table
class Thumb(db.Entity):
_table_ = 'thumbnails'
Id = orm.Required(str, index=True)
Image = orm.Optional(bytes)
the problem is that pony expects id to be an int, tries to convert and fails with an exception
aldo
have to go now, will connect tomorrow
Nick
Hi, I think I have a fix for some of the issues with python 3.12 support, would anyone here be in a position to give it a review? https://github.com/ponyorm/pony/pull/741
Alexander
aldo
good morning, I need to read a sqlite db that has this table
class Thumb(db.Entity):
_table_ = 'thumbnails'
Id = orm.Required(str, index=True)
Image = orm.Optional(bytes)
the problem is that pony expects id to be an int, tries to convert and fails with an exception
sorry, had to leave in a hurry yesterday. when doing db.Thumb.get(Id=id_) got this error Traceback (most recent call last):
File "python3.10/site-packages/pony/orm/core.py", line 4007, in get
try: return entity._find_one_(kwargs) # can throw MultipleObjectsFoundError
File "python3.10/site-packages/pony/orm/core.py", line 4114, in _find_one_
if obj is None: obj = entity._find_in_db_(avdict, unique, for_update, nowait, skip_locked)
File "python3.10/site-packages/pony/orm/core.py", line 4174, in _find_in_db_
objects = entity._fetch_objects(cursor, attr_offsets, 1, for_update, avdict)
File "python3.10/site-packages/pony/orm/core.py", line 4305, in _fetch_objects
real_entity_subclass, pkval, avdict = entity._parse_row_(row, attr_offsets)
File "python3.10/site-packages/pony/orm/core.py", line 4345, in _parse_row_
avdict[attr] = attr.parse_value(row, offsets, cache.dbvals_deduplication_cache)
File "python3.10/site-packages/pony/orm/core.py", line 2232, in parse_value
dbval = attr.validate(row[offset], None, attr.entity, from_db=True)
File "python3.10/site-packages/pony/orm/core.py", line 2534, in validate
val = Attribute.validate(attr, val, obj, entity, from_db)
File "python3.10/site-packages/pony/orm/core.py", line 2204, in validate
if from_db: return converter.sql2py(val)
File "python3.10/site-packages/pony/orm/dbapiprovider.py", line 550, in sql2py
return int(val)
ValueError: invalid literal for int() with base 10: 'Media/WhatsApp/Media/WhatsApp Images/Sent/IMG-WA0001.jpg40927'
aldo
the db is generated by another software and it's quite big. i think that pony expects a column id with int type, not sure if can opt out from that