Alexander
And than you can find a dog by primary key:
dog = Dog[dog_id]
And find an owner of this dog:
owner = dog.owner
Rozen
Yeah i know xD
Rozen
But i have like. Its a town with dogs that "have" many homes
Rozen
And i want to get every person that have that dog as a pet
Rozen
Like, those dogs choose where to eat, spend the time and sleep
Alexander
Then probably the relation should be many-to-many (two Set attributes). But anyway, if any human of this city is required to have a dog, then select(h for h in Human if h.pet == dog) looks correct. But the error says that the value of a dog variable is not a single dog, but a set of dogs. You can print the variable and see its value.
Rozen
hmmm ok
Rozen
i get
Rozen
Dog[3]
Alexander
Then it is strange that the error says that you are comparing Animal with a Set of Dog. I don't see any Set here
Rozen
me neither 😆
Rozen
but that's exactly what i have and the query i'm trying to do
Rozen
and that's what i get u.u
Rozen
(the error)
Alexander
Can you provide full exception traceback? It may contain some hints
Rozen
Dont know how xD
Alexander
The error
`<class 'pony.orm.sqltranslation.IncomparableTypesError'>
("Incomparable types 'Animal' and 'Set of Dog' in expression: h.pet == dog",)`
came with some traceback
Rozen
well, i don't know what maybe i've done wrong before
Rozen
but now that works
Rozen
sorry for the trouble
Rozen
noow i have another question
Rozen
if i have a function that returns an User object, and User inheritates from db.Entity
Rozen
if the .. scope that called the function that returned that User object it's wrapped in db_entity it will get that is the same user as in the table?
Rozen
or i should "load" it again?
Alexander
Yes, within the same db_session it will be the same object if primary key value is the same
Rozen
thanks :D
Rozen
Annnnnnnnnother silly question(sorry, i guess i don't have too much experience u.u)
Rozen
Hmm well basically i would ask "what could i do if the database is locked"
Rozen
i was thinking of just using @retry at best
Rozen
or try to make a buffer
Rozen
but to me that seems a little odd while using pony 😆
Alexey
Can you describe the scenario when you get the database locked?
Rozen
having 3 processes that access the same database at the same time
Alexander
In SQLite only one process can modify database at a time. After the process issues an INSERT, UPDATE or DELETE command, the database is in locked state. If another process tries to work with the database at this moment, it will be suspended until the first process finishes its transaction.
SQLite has timeout (which defaults to 5 seconds), after which the suspended process got exception "The database is locked". In order to avoid that exception, you need to complete transaction in the first process before the timeout.
In Pony a transaction can be finished in following ways:
- implicitly, upon exit from db_session scope
- explicitly, using commit() or rollback()
Your process that saved changes to database should perform commit() or rollback() after some portion of data was saved, or exit from db_session in order to have implicit commit. It should not stay within db_session indefinitely without performin commit or rollback
Rozen
mm
Rozen
to use the retry option
Rozen
only can used on @db_session?
Rozen
like..
Rozen
i cant do
with db_session(retry=3):
#code
Rozen
?
Alexander
Yes, this is Python restriction for context managers, their code cannot be automatically executed several times
Rozen
wokey ty 😆
Vitalii
while db_session.error(retry=3):
# codeeverything is possible in python ;)
Vitalii
No, here is it
with db_session.retry(3) as retry:
while retry: # code
Alexander
So you mean that we can add such extension to API
Vitalii
NO! :)
Rozen
another round of "Rozen's stupid questions!" yey!
Rozen
if i have db1 and db1
class hello(db1.Entity):
blablablal
Rozen
can i have like...
class wololo(db2.Entity):
helloes = Set("Hello")
?
Alexey
hey
nope, all related entities should belong to the same database
Vitalii
yes you can afaik
Alexey
but if they are not related, then you can
Vitalii
right, i didn't notice they were related
Rozen
hmm wokey
Rozen
and if i have... a relational table in one of the databases?
Rozen
well, actually i have no idea what i'm talking about 😆
Alexey
haha)
Alexander
Why do you want to split tables between several databases?
It is better to keep related tables together, because then the database can enforce foreign key constraints in order to be sure that all used ids have corresponding rows.
It is possible to keep tables in different databases, but then you are vulnerable to data consistency issues and need to process joins manually.
Rozen
it was just an idea 😆
Alexander
By default try to store everything in a single database, it will be simpler
Rozen
yes yes 😆 i was and idea beause i wanted to avoid to have lots of database locking 😆
Rozen
i'm having tons of database writing at the same time 😆
Rozen
i have retry=30 and everything but it crashes anyway 😆
Alexander
That means that db_session from which you perform an update stays open for too long. Ideally, all transactions which perform writing to the database should be very short.
Maybe you start db_session, perform an update and then start some unrelated actions, like, sending e-mail via SMTP. In that case the database remains locked until the email is sent, and it may take a long time. It is better to perform such long unrelated operations outside of db_session
Rozen
mmmmmmmmm
Rozen
i'll see
Mikki
Smaller transactions is always better. If you have to retry 30 times, think about why you wanted to use a db again :p
Rozen
ajamm
Rozen
This works?
with db_session:
hoomans = select(h for h in Human)
for h in hoomans:
print(h.name)
Rozen
(or it's even necesary to use de db_session for just a select?)
Alexander
You should wrap all interactions with objects in a single db_session:
with db_session:
hoomans = select(...)
for h in hoomans:
print(h.name)
An attribute access like h.name potentially can lead to SQL query, and SQL queries are possible inside db_session only.
Rozen
ok ok, got it 😆
Rozen
i'm not quite sure how generators work so maaaybeee it worked (?)
Rozen
mm
Rozen
but if i do hoomans = (h.name for h in Human)
?
Alexander
generators are lazy, the real operation will be performed later. You need to use list comprehension to eval result inside db_session:
with db_session:
hoomans = select(...)
names = [h.name for h in hooman]
Then you can use names outside of db_session
Rozen
right
Rozen
thanks :D
Mikki
Helleau!
male
hello :D