
Vitaliy
04.08.2018
08:05:52
Hi, everyone! Is there a way to track changes on Sets (M2M relationship)? I see only one way: to introduce intermediate entity and create before/after_insert callbacks, but it is not comfortable to work with (to much refactoring of existing code needed). So can I track changes of M2M Sets without intermediate entity?

Luis
04.08.2018
15:19:18
Hi Alex, how to can declarate this relationship

Google

Alexander
04.08.2018
15:42:12
class Cliente(db.Entity):
_table_ = "clientes"
id = PrimaryKey(int, column="idClientes")
empresa = Optional(str, column="Empresa")
alta = Optional(str, column="Alta")
facturas = Set("Factura")
class Factura(db.Entity):
_table_ = "factura"
id = PrimaryKey(int, column="idFactura")
total = Optional(Decimal, column="Total")
...
cliente = Optional("Cliente", column="Clientes_idClientes")


Luis
04.08.2018
15:45:34
Thanks, i try and and comment ?
class Clientes(db.Entity):
_table_ = "clientes"
id = PrimaryKey(int, column = "idClientes")
Empresa = Optional(str, column = "Empresa")
Alta = Optional(str, column = "Alta")
facturas = set("Factura")
class Factura(db.Entity):
_table_ = "factura"
id = PrimaryKey(int, column = "idFactura")
Total = Optional(Decimal, column = "Total")
Fecha = Optional(datetime, column = "Fecha")
Resta = Optional(Decimal, column = "Resta")
Pagos = Optional(str, column = "Pagos")
clientes = Optional(Clientes, column = "Clientes_idClientes")
pony.orm.core.ERDiagramError: Reverse attribute for Factura.clientes not found

Alexander
04.08.2018
18:02:47
facturas = set("Factura")
You need to use Set, not set
Also, it is more traditional to name all models in singular, not in plural, because an object represent a single instance of a model. It looks strange when Factura is singular, but Clientes is plural

Luis
04.08.2018
18:06:38
Wow, great i am a noob ?
Thanks Alex

Alexander
04.08.2018
18:10:03
Sure

Luis
04.08.2018
18:11:03

Alexander
04.08.2018
18:11:22
Cool. It is more traditional in Python to start attributes names with a lowercase letter, although it is not absolutely necessary

Luis
04.08.2018
18:14:32
I need read the pep's

Yoni
04.08.2018
23:29:56
Hi, does pony orm work in aws lambda ?

Google

Vitaliy
06.08.2018
08:15:21


Alexander
08.08.2018
17:54:10
Hi guys! We just released Pony ORM 0.7.6 Release Candidate 1
This release should fix most bugs introduced in 0.7.4 during a massive refactoring
Also it adds some nice things like support of Python 3.6 f-strings (literal string interpolation):
https://github.com/ponyorm/pony/releases/tag/0.7.6rc1
Changelog:
# Pony ORM Release 0.7.6rc1 (2018-08-08)
## New features
* f-strings support in queries: select(f'{s.name} - {s.age}' for s in Student)
* #344: It is now possible to specify offset without limit: query.limit(offset=10)
* #371: Support of explicit casting of JSON expressions to str, int or float
* #367 @db.on_connect decorator added
## Bugfixes
* Fix bulk delete bug introduced in 0.7.4
* #370 Fix memory leak introduced in 0.7.4
* Now exists() in query does not throw away condition in generator expression: exists(s.gpa > 3 for s in Student)
* #373: 0.7.4/0.7.5 breaks queries using the in operator to test membership of another query result
* #374: auto=True can be used with all PrimaryKey types, not only int
* #369: Make QueryResult looks like a list object again: add concatenation with lists, .shuffle() and .to_list() methods
* #355: Fix binary primary keys PrimaryKey(buffer) in Python2
* Interactive mode support for PyCharm console
* Fix wrong table aliases in complex queries
* Fix query optimization code for complex queries
As it is a pre-release, it will not be installed using an usual pip install pony command. You can install it using
pip install pony --upgrade --pre
or
pip install pony==0.7.6rc1
Tomorrow we plan to release official 0.7.6 release


Vitaliy
09.08.2018
05:28:11
Cool! What is f-strings? Are there any docs?

Alexander
09.08.2018
05:31:33
https://realpython.com/python-f-strings/


Vitaliy
09.08.2018
09:45:49
It seems I have discovered a bug.
I have a following entity (simpified):
class IpAddress(db.Entity):
network = Required(lambda: IpNetwork)
host = Required(int, size=8, unsigned=True, min=1, index=True)
PrimaryKey(network, host)
@property
def str(self):
"""Hybrid property"""
return concat(self.network.octets, self.host)
@classmethod
def find1(cls, ipaddr):
return cls.get(lambda ip: concat(ip.network.octets, ip.host) == ipaddr)
@classmethod
def find2(cls, ipaddr):
return cls.get(lambda ip: ip.str == ipaddr)
If I call IpAddress.find1('127.0.0.1') it is OK. If I call IpAddress.find2('127.0.0.1') once it is OK, but further calls throwing exception like this:
File ".../pony/orm/core.py", line 5304, in extract_vars
try: value = extractor(globals, locals)
TypeError: 'str' object is not callable
To make my app works before you'll resolve this issue I have replaced func.__globals__ to {} at line #5438 in core.py


Alexander
09.08.2018
11:09:58
Thanks for reporting! I found the reson for a bug and will wix it soon
@vitalium, I fixed the bug and pushed the fix on GitHub. Thanks again, your help with finding bugs is invaluable

Vitaliy
09.08.2018
12:03:07
Thank you too! Pleased to be helpful :)

Alexander
09.08.2018
13:52:22

Eugene
10.08.2018
10:28:34
sara when we whill have new terminator movie? Will be it like a shit, or it will be nice movie?

Alexander
10.08.2018
10:32:15
I think that this time Sara plays on the side of the machines

Eugene
10.08.2018
10:33:27
it is pity. No chance for salvation. Only one hope remaining - reprogrammed T-800.

Alexander
10.08.2018
12:00:56
Hi everybody! We've released Pony ORM 0.7.6
https://blog.ponyorm.com/2018/08/10/pony-orm-release-0-7-6/
https://github.com/ponyorm/pony/releases/tag/0.7.6

Windfarer
10.08.2018
13:36:43
?

Luckydonald
10.08.2018
14:57:54
Interactive mode support for PyCharm console
Tell me more

Alexander
10.08.2018
15:17:05
Usually Pony requires that all queries we executed from db_session, and objects cannot be updated after the db_session is over. But this is inconvenient when working from console. Because of this Pony creates implicit db_session when working from console.
Pony has special flag pony.MODE. If it is set to INTERACTIVE, Pony allows writing queries without wrapping them into db_session. To determine the mode Pony performs some special checks for main application module. Checks for interactive mode were:
if not hasattr(main, '__file__'):
pony.MODE = 'INTERACTIVE'
As it turns out, this check is not sufficient when console is opened from PyCharm. So, for PyCharm we've added additional test:
if getattr(main, 'INTERACTIVE_MODE_AVAILABLE', False):
pony.MODE = 'INTERACTIVE'

J J
10.08.2018
15:18:32
Oooh
I always wondered why I had to do with db_session in pycharm and not from terminal

Google

J J
10.08.2018
15:19:19
Thanks for the update

Alexander
10.08.2018
15:19:40
Cause PyCharm console uses some __file__
Guys, we have a question.
In one of future Pony releases we will change the way how we name tables. So, we need to upgrade users' databases to change names.
Here is the question: what is the most comfortable way to do it?
We have some ideas, but we are not sure about them.
a) Add db.upgrade(from_pony_version) command. Which will run ALTER TABLE commands.
b) Add special table pony_version which will keep version that was used to create this tables. If you use db.generate_mapping(allow_auto_upgrade=True) Pony will automatically perform ALTER TABLE after connection to database.
c) Like Django require users to manually do ALTER TABLE for new specification.
Any ideas and thoughts will be appreciated.

Alexander
10.08.2018
15:35:28
The question is, what way is best suitable to upgrade database on servers. It looks a bit like a migration, but not quite so

Alexander
10.08.2018
15:36:04
My ideas why this ways are not that good.
a) User can forgot his previous version.
b) User can have no access to create tables inside production schema
c) Too hard, doesn't seem like pony way.


Alexander
10.08.2018
15:38:02
I think (a) is the most convenient way, but I may be wrong
So, for example, someone want to upgrade Pony on server. New version of Pony expects new tables names, and also know previous names. Pony connect to database, and need a way to determine do database schema needs upgrade or not, and should Pony perform ALTER TABLE commands right now
This is the changes we want to do for table names in some future release:
1) Rename many-to-many tables from entity1_entity2 to entity1_attr1: "course_student" -> "course_students". This is necessary for correct handling of situation when pair of entities has multiple many-to-many relationships
2) If very long name of table or constraint was cut because of database name length limitation, add unique hash to it "some_very_long_table_nam" -> "some_very_long_ta_f0e3df4e". This way each name will be unique

J J
10.08.2018
15:56:02

Alexander
10.08.2018
15:59:04
So you prefer (b) option
with automatic upgrade when new version of pony were installed

J J
10.08.2018
16:02:31
I do. Seems simplest

Alexander
10.08.2018
16:03:51
Actually (b) looks like a good option to me

Alexander
10.08.2018
16:05:36
It has some complicated cases.
What if we see no tables?
What if user named some of these tables by himself?
Again - no access to create new tables.


Alexander
10.08.2018
16:14:51
If pony_version table is missing it may mean one of three things:
1) Tables were not created using Pony, Pony just used to connect to pre-existing tables. In that case a developer should not call generate_mapping(create_tables=True) or execute migrate.py apply. It is possible to specify correct _table_ name manually.
2) The database is empty and on generate_mapping(create_tables=True, allow_auto_upgrade=True) call Pony should create all tables, including pony_version table.
3) The database were created using previous version of Pony. It contains most of tables, but some of them have obsolete names. On generate_mapping(create_tables=True, allow_auto_upgrade=True) Pony should upgrade existing tables and add missing ones.
The only problem is how to correctly distinguish (2) and (3) in all situations


Vitaliy
10.08.2018
21:02:37
How can I explicitly exit db_session in pycharm console?
Sometimes I need to migrate existing data from previous project via external API. Earlier to do it I called db_session.__exit__() then db.drop_all_tables(with_all_data=True), then db.create_tables(), then db_session.__enter__(). Finally after that I can create new entities with new data, but now it doesn't work, because I never cannot leave db_session.

Alexander
10.08.2018
21:04:03
I think you can do
db.commit() # to save previous changes
db.rollback() # to close session
db.drop_all_tables(with_all_data=True)
db.create_tables()
But functions explicitly wraped with db_session like (db.drop_all_tables and db.create_tables) should auto-close previous implicit db_session. I need to check that

Vitaliy
10.08.2018
21:10:39
Fantastic! It works! :)

Alexander
10.08.2018
21:13:14
I tried, and it works from PyCharm console:
>>> from pony.orm.examples.university1 import *
>>> populate_database()
>>> select(s for s in Student).show()
>>> db.drop_all_tables(with_all_data=True)
>>> db.create_tables()
So, it seems, nothing special is required, and implicit db_session auto-closes correctly before db.drop_all_tables

Google

Alexander
12.08.2018
13:11:01
Добрый день
Подскажите как реализоватьт Concrete Table Inheritance. Только ручками? Прописывая в каждом классе одинаковые атрибуты.
Например, есть класс Документ. У каждого документа есть Номер и Дата и возможно другие общие поля. И видов документов может быть много.
Может разработать разные виды наследования?

Alexander
12.08.2018
13:19:05
Good day Alexander! This chat is in English.
At this moment Pony support single-table inheritance only, we plan to add other types of inheritance in the future.
If you want to have several classes with similar attributes, it is possible to do, but I'm away from the computer and will show it later

Alexander
12.08.2018
13:20:22


Alexander
12.08.2018
13:20:33
It is possible to use similar approach as shown in this post
In principle, it is possible to create entity classes dynamically. Simplified example:
from pony.orm import *
from pony.orm import core
db = Database()
def define_person_entity(db):
attrs = []
attrs.append(('name', Required(str)))
attrs.append(('age', Required(int)))
Person = core.EntityMeta('Person', (db.Entity,), dict(attrs))
define_person_entity(db)
db.bind('sqlite', ':memory:')
sql_debug(True)
db.generate_mapping(create_tables=True)
with db_session:
p1 = db.Person(name='John', age=18)
p2 = db.Person(name='Mike', age=20)
persons = select(p for p in db.Person)[:]
You can use the same idea to generate entity definitions based on information from some configuration file

Vitaliy
14.08.2018
15:27:46
Hi, Alexander! Is there a way to share pony objects across different threads?

Alexander
14.08.2018
15:29:57
Hi Vitaliy! Can you describe your use-case in more details?

Vitaliy
14.08.2018
15:34:33
In my project there are support ticket system. I working now on notifications when a new Message has been added. In after_insert callback I call async task (function in new thread) for sending an e-mail to admin. Currently I pass self argument from Message.after_insert to send_notification task.

Alexander
14.08.2018
15:39:14
In a new thread you should use a separate db_session. You can pass self.id instead of self and re-fetch object by id, or you can pickle some data (including Pony objects) in the first db_session and unpickle them in the second db_session
If the function that you wrap with db_session is generator, the db_session will suspend on yield and resume on next(gen). It is possible to resume generator in another thread. It was implemented for better compatibility with async frameworks like Tornado. Maybe you can use it, but for your case it looks like an overkill

Vitaliy
14.08.2018
15:48:05
I use flask and have subclassed Thread to invoke tasks within app and request contexts. It seems pickling can help, thanks

Matthew
14.08.2018
21:00:47
data = Required(LongUnicode, 1024 * 1024 * 16)
TypeError: Max length is not supported for CLOBs