A
Okay no worries, thanks anyway!
A
Do you want me to raise an issue on Github for this?
Alexander
It will be part of migrations, probably not necessary to have a separate issue for that
A
👍
El Mojo
B
Hello.
Is there a convenient way to specify a default value in Declaring Entity Class by Python function with Context?
For example, in SQLAlchemy:
def mydefault(context):
return context.get_current_parameters()['counter'] + 12
t = Table('mytable', metadata_obj,
Column('counter', Integer),
Column('counter_plus_twelve', Integer, default=mydefault, onupdate=mydefault)
)
Thank you.
Alexander
Hi! You can specify default for attribute, but default with context is not supported:
def my_function():
return randint(0, 100)
class MyEntity(db.Entity):
my_attr = Required(int, default=my_function)
onupdate for attribute is not supported, you can try to use hooks for this:
https://docs.ponyorm.org/api_reference.html#entity-hooks
class MyEntity(db.Entity):
my_attr = Optional(int)
before_insert(self):
if self.my_attr is None:
self.my_attr = ...
before_update(self):
self.my_attr = ...
Context-Sensitive Default Functions look like an interesting idea, maybe Pony should have something like that
Alexander
Mario
B
B
Let's suppose that I want to use table2 simply as a list of valid non-repeating values for some column in table1, and NOT NULL, so that the database does not allow adding an arbitrary value. But I do not need a one-to-one relationship, otherwise there will be too many records in table2. I've tried it in different ways, but the pony requires "specify both ends of a relationship" and binds a row to a row.
For example:
class Table1(db.Entity):
id = PrimaryKey(int, auto=True)
name = Required(str, unique=True)
source = Required('Table2')
class Table2(db.Entity):
name = PrimaryKey(str, 10)
table1 = Optional(Table1)
Doesn't work like that:
pony.orm.core.ConstraintError: Cannot unlink Users[1] from previous Auth_Sources['google'] object, because Users.source attribute is required
Alexander
Instead of
table1 = Optional(Table1)
it should be
table1 = Set(Table1)
because one source name can be used in multiple Table1 records
B
Solution
Solution
Am having issue with db_session is required when working with database
Solution
I used the example from the doc
Alexander
When you do something with Pony objects, you need to do it inside db_session. Like:
with db_session:
p1 = Person(name="John", age=20)
db_session opens a connection to the database and handles transactions
Solution
Still throwing the same error
Solution
Wil9
Solution
Copy the code I paste down here
Alexander
probably you aren't wrap ALL lines when you work with objects with the db_session
Solution
from pony.orm import *
from pony.py23compat import PY37
db = Database()
class Person(db.Entity):
name = Required(str)
age = Required(int)
cars = Set('Car')
class Car(db.Entity):
brand = Required(str)
model = Required(str)
owner = Required(Person)
db.bind(provider='mysql', host='localhost', user='sqluser', passwd='Bayo4real', db='ponydb')
db.generate_mapping(create_tables=True)
set_sql_debug(True)
p1 = Person(name='John', age=20)
p2 = Person(name='Mary', age=30)
p3 = Person(name='Mike', age=40)
c1 = Car(brand='Ford', model='Focus', owner=p1)
c2 = Car(brand='Audi', model='A4', owner=p2)
c3 = Car(brand='BMW', model='X5', owner=p3)
with db_session:
p = Person(name='John', age=20)
Car(make='Audi', model='A4', owner=p1)
# commit() will be done automatically
# database session cache will be cleared automatically
# database connection will be returned to the pool
Alexander
with db_session should wrap ALL lines starting from p1 = Person(...)
Solution
👍
Solution
Got it
Solution
How can I use pony to map CSV file into database?
Alexander
Pony does not work with csv files, you need to use csv standard library to read csv file first, and then you can create Pony object for each csv row
https://docs.python.org/3/library/csv.html
Solution
T hanks the first time in my history of coding I see a great community
B
I agree with great community!
Karsten
Hi community,
I use pony in my application. There are often multiple instances of the application. Is there some way to notify all instances when a record has been inserted?
Karsten
Alexander
No, pony does not have such notifications. You need to implement it yourself with something like Redis
Karsten
Alexander
Solution
Alexander
The same way as you created Person objects, but for your own entity class
Solution
>>> import csv
>>> with open('names.csv', newline='') as csvfile:
... reader = csv.DictReader(csvfile)
... for row in reader:
... print(row['first_name'], row['last_name'])
...
Eric Idle
John Cleese
>>> print(row)
{'first_name': 'John', 'last_name': 'Cleese'}
Solution
alright thanks
B
Should I disconnect() db or others methods at the close of my program?
Alexander
It is not strictly necessary, I think. But if you use threads, you need to do db.disconnect() in thread before it finishes
B
Clearly, Thanks!
I do.
When will pony support async queries?
I do.
Ah ok, thanks.
Bob
hey all, I have a query issue I'm hoping to be able to figure out
Bob
I am trying to call db.select(blah blah blah) without making use of any entity classes
Volbil
Bob
I have a constant PEOPLE which is a list of multiple names
I would like my adapted tsql to look something like 'select * from txs where person in PEOPLE'
Bob
Why?
because entities and everything else in the db are defined in another repo that I'm not allowed to use for this use case
Volbil
Well, in that case you have to use raw SQL queries
Volbil
Pony require entity definitions in order to make queries
Bob
so I've tried
db.select('select * from txs where person in $(PEOPLE)) but that tries to pass the list as an ARRAY rather than a list
Bob
maybe easiest solution is to copy pasta entity definition from the other repo. But that could cause future complications if the entity definition changes remotely
Volbil
Volbil
You can make package containing entity definitions and use it on both projects
Bob
well ty for your help sir, Ill play around with this some more tonight
Bob
ooh good idea, I like that
Mattia
Hello
exploring Pony I'm trying to add a column to the db proposed in the test example:
Mattia
class Person(db.Entity):
name = orm.Required(str)
age = orm.Required(int)
cars = orm.Set('Car')
test = orm.Optional(int)
class Car(db.Entity):
make = orm.Required(str)
model = orm.Required(str)
owner = orm.Required(Person)
Mattia
specifically I would like to add the test attribute to Person
Mattia
But when I launch db.generate_mapping() I would have expected to add the column to the db, while I get this error back: pony.orm.dbapiprovider.OperationalError: no such column: Person.test
Mattia
You would know which is the correct method for achieve this goal?
Volbil
Volbil
Mattia
Here because! Thanks so much 👍👍👍
Volbil
Ben
Is there any reason doing orm.sum(x.amount for x in y) is significantly slower (by about 10x) than doing orm.select(x.amount for x in y).sum()
Ben
I'm very confused, is there a recommended way?
Alexander
It should produce the same query.
If you perform these queries one after the another, the table rows and indexes will be cached in memory, and the second query execution should be significantly faster
Ben
hmm
Ben
that's probably why then, thanks!
Bob
Radim
Hey, any updates on Python3.10 support?
Alexander
It's almost done.
Our checklist is now
- one (known) bug
- coverage check
- make release text
- publish it
ETA before 9th Jan
Radim
sounds great! keep up the good work, thanks
Christian
Hi. I'm getting an error here in the last line, because self.user comes back as Multiset: TypeError: unsupported operand type(s) for +=: 'Multiset' and 'decimal.Decimal'. I'm being a little stupid - how can I get the connected user object, so I can work with it here?
Christian
class LoanEntry(db.Entity):
user = Set(lambda: User)
created = Required(datetime, default=datetime.utcnow)
loan = Required(Decimal, precision=9, scale=2)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.update_total(self.loan)
def update_total(self, loan):
self.user.loan_total += loan
Christian
I'm trying to do the following: Every time a user adds a new loan, it creates a new LoanEntry and also adds the new loan to the total amount of money the user has loaned so far.