Adam
is there a quick way to use pony to convert sqlite to mysql?
Alexander
You mean you have some SQLite database initially created without Pony, and you want to convert it to MySQL database?
Adam
no with pony
Alexander
There is no ready code for that. You can try the following: 1) Declare entities inside a function def define_entities(db): class Foo(db.Entity): ... class Bar(db.Entity): ... 2) create two databases with these entities, one for SQLite and another for MySQL: db1 = Database(**sqlite_params) define_entities(db1) db1.generate_mapping() db2 = Database(**mysql_params) define_entities(db2) db2.generate_mapping(create_tables=True) 3) In a loop, load objects from the db1 create similar objects in db2, periodically performing commit(); rollback(); to commit changes and clear in-memory cache. It may be a bit tricky to process all objects and related objects this way.
Adam
thank you
Jonah
you can also try metaclasses for this
Jonah
Foo = type('FooCls', (db.Entity,), {})
Anonymous
Hi, i got DatabaseSessionIsOver before and i asked here and then i used db_session context manager, and it worked. but now, i get the same error for another section although i use this context manager CODE: with actions.db_session: n, views = 0, 0 for n, post in enumerate(ad.its_posts): views += get_views(post) in traceback it seems like the error comes from for n, post in enumerate(ad.its_posts):
Anonymous
actions is a module that provide some functions
Matthew
make sure the code that gets "ad" is in the same db_session as the code that uses "ad"
Anonymous
lemme check it out
Anonymous
it is, as far as i understood you.
Matthew
you are creating a new db_session in the first line of the code you posted
Matthew
but the ad must have been created before that
Anonymous
the code is ad = actions.AdActions.get_ad(args['id']) with actions.db_session: n, views = 0, 0 for n, post in enumerate(ad.its_posts): views += get_views(post) however, actions.AdActions.get_ad is wrapped by pony.orm.db_session as well
Matthew
but a different db_session I think
Anonymous
but a different db_session I think
well, in action.py i import db_session from pony.orm import db_session, select and i use it throughout the code, and also where i did with actions.db_session it is referring to the same db_session, isn't it?
Matthew
each db_session is independent unless they are nested i beleive
Anonymous
ok i solved it by make ad = actions.AdActions.get_ad(args['id']) in the context manager
Matthew
cool
Anonymous
Thanks a lot
Matthew
no problem
Luis
Hi Alex, there is a way to differentiate in select I have two records with the difference in accent but to insert it does not give me a problem but at the time of consulting if
Alexander
Hi Luis, can you show an example?
Luis
Luis
pony.orm.core.MultipleObjectsFoundError: Multiple objects were found. Use Almacen.select(...) to retrieve them
Luis
I am use get an select and this retrieve them
Alexander
What attributes do you specify in this get query? I suppose this column is not one of them?
Luis
ida = select( c for c in tabla.Almacen if c.nombre == datos[i][0])[:]
Luis
ida = tabla.Almacen.get(nombre=datos[i][0])
Luis
Only this column
Luis
I will try use raw_sql
Alexander
Yes, you need to use raw_sql. Like, nombre = datos[i][0] query = select(c for c in Almacen if raw_sql('c.nombre = $nombre collate utf8_bin')) ida = query.get()
Alexander
If searches for this column are always case-sensitive, you can define column like class Almacen(db.Entity): ... nombre = Required(str, 200, sql_type='VARCHAR(200) COLLATE utf8_bin') Then you can use normal == comparison to get case-sensitive results
Luis
Thank a lot Alex, I will try this
Matthew
Good morning, I have some code which every x minutes updates a pony object, for example: obj.a = 1 obj.b = 2 When I do these updates, I get an OptimisticCheckError, which I understand. Is there a way to only consider the object updated if the values which have been set are different to the old values? I'm trying if statements before setting each value, but I wonder if there is a better way.
Alexander
Pony uses read committed transaction isolation level by default, this is a default level for PostgreSQL and many other databases. That means that the state of the object at the end of a transaction can be different from the values you read from the database, if it was modified by some concurrent transaction. If you do obj.a = 1 you say that at the end of transaction obj.a should be 1 no matter what other transactions are doing. To avoid OptimisticCheckError you can do get_for_update instead of get, this way concurrent transactions that are trying to modify the same object will wait until the previous transaction finishes. It may lead to some slow down but allows to avoid the error. But you need to be sure that if a transaction does get_for_update for several objects A, B, C, all other parallel transactions do it in the same order, otherwise, you can get a deadlock. Another way is to check values before assigning them to object: for key, value in new_values: if getattr(obj.key) != value: obj.set(**new_values) break
Matthew
The latter example is what I'm doing and I think that makes sense, thanks!
Anonymous
i am trying to store my own data type, _List which inherits list but with few methods, how can i call those methods after i retrieve the list from Pony [without recall _List with the retrieved value, i.e _List(car.previous_owners)]? like car.previous_owners.contact_each_owner() which car.previous_owners is a _List object and contact_each_owner() is a method of _List.
Anonymous
[i store it as Json]
Alexander
User-defining types are not supported, as it is non-trivial to convert them to SQL in queries What methods did you add to this _List class?
Adam
why am i getting "ValueError: Value for attribute Hash.hash is too long. Max length is 255, value length is 256" for mysql and not sqlite when there both using the same str declare?
Alexander
In PostgreSQL and SQLite it is possible to declare a column with the TEXT type and store arbitrary big or small string into it. In MySQL TEXT is a special data type which stored outside of the table row and is very slow to access. A usual text column such as first_name or phone_number in MySQL should be declared as VARCHAR(nnn), where nnn is the max possible size for the string. So, when you declare a column as Required(str) or Optional(str) without specifying the max size, Pony needs to specify something and uses VARCHAR(255) as a default. You can specify some bigger value: Required(str, max_len=1000)
Anonymous
User-defining types are not supported, as it is non-trivial to convert them to SQL in queries What methods did you add to this _List class?
i added few methods like contact_each_owner and add_owner, remove_owner and such. Can't pony hold a list of methods for a user-defined datatype and then just return Query result which inherits from that user-defined data-type so it could have the methods?
Alexander
Expressions like car.previous_owners already return an object of a special class, which enables attribute lifting (in Python as well as in queries). https://docs.ponyorm.org/working_with_relationships.html#attribute-lifting You can do things like car.previous_owners.phone_number or car.previous_owners.country.name, which will return all phone numbers and all country names of previous owners The real class for car.previous_owner as well as the class for car.previous_owner.country are constructed on-the-fly, and it may be hard to add an additional layer of custom-defined classes to this. Instead, you can add such methods to Car class itself. Then you can do: car.contact_each_previous_owner() car.add_owner(...) etc.
Adam
Thank you again alexander
Matthew
I have an integer column that is a counter. Multiple simultaneous overlapping database sessions sometimes increment the counter, do I want optimistic, volatile, both, or something else to avoid getting OptimisticCheckError ?
Alexander
You need to use get_for_update when retrieving this object from the database. optimistic or volatile are not suitable here
Alexander
But if you have several such objects, all sessions should select them in the same order
Anonymous
Hi, what's the easiest way to make a hook onto Pony? so i can get an update for every new instance, like override class MyClass(pony.orm.SomeClass): def __init__(self, *args, **kwargs): print("NEW INSTANCE: ...") super().__init__(*args, **kwargs) and then pony.orm.SomeClass = MyClass, But 1) i don't know of a main class which i can inherit to this task. 2) maybe there is more-friendly way?
Anonymous
ok i will just inherit from both my Hooker and db.Entity class Car(db.Entity, Hooker)
Robert
Hi Pony gurus, is this something anyone has experienced?
Robert
File "/root/teamplot/massa/lib/python3.8/site-packages/engineio/middleware.py", line 74, in call return self.wsgi_app(environ, start_response) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app response = self.handle_exception(e) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception reraise(exc_type, exc_value, tb) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise raise value File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise raise value File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1948, in full_dispatch_request rv = self.preprocess_request() File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 2242, in preprocess_request rv = func() File "/root/teamplot/massa/lib/python3.8/site-packages/pony/flask/__init__.py", line 7, in _enter_session session.enter() File "/root/teamplot/massa/lib/python3.8/site-packages/pony/orm/core.py", line 464, in enter db_session._enter() File "/root/teamplot/massa/lib/python3.8/site-packages/pony/orm/core.py", line 467, in _enter assert not local.db_context_counter AssertionError
Anonymous
File "/root/teamplot/massa/lib/python3.8/site-packages/engineio/middleware.py", line 74, in call return self.wsgi_app(environ, start_response) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 2450, in wsgi_app response = self.handle_exception(e) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1867, in handle_exception reraise(exc_type, exc_value, tb) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise raise value File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 2447, in wsgi_app response = self.full_dispatch_request() File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1952, in full_dispatch_request rv = self.handle_user_exception(e) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1821, in handle_user_exception reraise(exc_type, exc_value, tb) File "/root/teamplot/massa/lib/python3.8/site-packages/flask/_compat.py", line 39, in reraise raise value File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 1948, in full_dispatch_request rv = self.preprocess_request() File "/root/teamplot/massa/lib/python3.8/site-packages/flask/app.py", line 2242, in preprocess_request rv = func() File "/root/teamplot/massa/lib/python3.8/site-packages/pony/flask/__init__.py", line 7, in _enter_session session.enter() File "/root/teamplot/massa/lib/python3.8/site-packages/pony/orm/core.py", line 464, in enter db_session._enter() File "/root/teamplot/massa/lib/python3.8/site-packages/pony/orm/core.py", line 467, in _enter assert not local.db_context_counter AssertionError
del.dog please
Anonymous
OwO that's cool https://docs.ponyorm.org/api_reference.html#entity-hooks nevermind
Robert
del.dog please
How do you mean? Should one not paste logs here?
Alexander
Hi Pony gurus, is this something anyone has experienced?
Thanks for reporting, it looks like a bug. I can’t check it right now, will answer tomorrow.
Robert
Thanks for reporting, it looks like a bug. I can’t check it right now, will answer tomorrow.
Thanks, so no deleting the log then :) Let me know if you need any additional info. It was run on Debian, installed from pip3. I can share more details if needed
Alexander
What Pony version do you use? Latest release?
Robert
I have been running the exact same app in a Windows development environment (under Anaconda) w.o. seeing the error, but just now after installation to a Debain system, it appeared.
Robert
On another matter, if I want to validate some data before putting it into the database? Is class @property getters and setters and making the database columns private members of the db.Entity class (e.g. __member = orm.Required(...) ) the way to go, or is there some better way in Pony?
Anonymous
before_update
Volbil
before_update
Yes, this one
Volbil
You also can use before_insert
Volbil
https://docs.ponyorm.org/api_reference.html?highlight=before_insert#before_insert
Robert
Thanks
Anonymous
i got this error without any message https://del.dog/pelorriboc.py
Robert
https://docs.ponyorm.org/api_reference.html?highlight=before_insert#before_insert
On this thread, seems from the documentation it does not do exactly what I need. Example use case: a string column stores emails and those should be validated before updating the filed. Now, if the validation fails, I don't want to go ahead with the commit, but rather send some error message. I cannot find anywhere that this is the behaviour. Perhaps a nice thing to add to Pony would be to have something like a hook that can be given in the Entity definition, like email = orm.Required(str, update_hook=my_update_hook).
Maik
is there a way to get an query entities with case sensitivity? for exampe return only when key="Hhh"and not when key="hhh"? (i use mysql database)
Lucky
it's too long
Is that an official statement from the ponyorm admins?
Lucky
That was never a problem in the past. If that is just your own preference, please don't call out others like they did something wrong. Additionally if it's posted here it's searchable, helping others if they encounter the same issue
Lucky
i got this error without any message https://del.dog/pelorriboc.py
In fact I personally wouldn't even bother to look at pastebin links, when everything you need to do is paste them in here. If you need a link, you can do that easy: https://t.me/ponyorm/16633
Anonymous
Is that an official statement from the ponyorm admins?
No 🤷‍♂️ It’s just blocking the chat with long message, but in the end, i am not admin.. I can’t tell you what to do🤷‍♂️
Alexander
As an admin, I'm ok with long tracebacks :) It is possible to use pastebin.com or something like that as well
Anonymous
In fact I personally wouldn't even bother to look at pastebin links, when everything you need to do is paste them in here. If you need a link, you can do that easy: https://t.me/ponyorm/16633
That’s why del.dog has a preview. You don’t even need to press the link . (e.g https://del.dog/pelorriboc.py) Just look at the photo, you can press to big it..that’s pretty cool