Lucky
Lucky
So these migrationes are currently only ponyorm's own migrations, and not user defined changes?
If so,
Will there be an easy way to use it for own migrations?
I heard django has a way of doing migrations if the user changed the data objects later. (Files numbered 01, 02, 03 etc., as far as I heard)
Alexander
They are two different things, which will be introduced at the same time - Pony version-dependent upgrades and user-defined migrations. In order to start using user-defined migrations we need to rename many-to-many tables, that will be the first version-dependent upgrade which will be required to anybody who want to use previously defined tables with Pony 0.8
Alexander
User-defined migrations will look pretty much like in Django
Alexander
Try to add sql_debug(True) before db.generate_mapping().
You will be able to see which tables are created and how INSERT command looks
Anonymous
It's that it's creating a new connection, but not to the same db?
Anonymous
It almost feels like a scope problem, but I don't quite understand how it loses it.
Alexander
I don't understand the reason of the problem yet. Can you for test purpose specify the database filename in db.bind(...) with absolute path?
Anonymous
Wow. that's it.
Anonymous
Thank-you for your help!
Alexander
It is strange. Probably click magic somewhat conflicted with pony magic. I'll investigate that
Anonymous
Yeah, no doubt... sometimes magic is great, sometimes it does this. Most of the time it's great ;) Pony is such a neat tool.
Alexander
@RuralOtter can you please print db.provider.pool.filename after db.bind(...), after db.generate_mapping(...) and inside the @db_session? Is it different or the same?
Anonymous
without the absolute path, each time it outputs: .\mapcatalog.sqlite
Alexander
What operation system do you use?
Anonymous
I've now put os.path.abspath("mapcatalog.sqlite") in the db.bind call.
Anonymous
this is on windows 7
Alexander
Ok, thank you
Anonymous
My pleasure, glad to contribute—even if it's only bugs haha
Romet
Welcome!
stsouko
Hello! is it possible to do st like this?:
def load_tables(db, schema):
class B(db.Entity):
_table_ = (schema, 'molecule')
a = Required('A')
return B
class A(db.Entity):
b = Optional('B')
b1=load_tables(db, 's1')
b2=load_tables(db, 's2')
stsouko
i want to create separate tables for B
Alexander
You cannot have several entities with the same name in the same schema, but you can write generic code which creates similar entities with different names:
from pony.orm.core import EntityMeta
def load_tables(db, schema, class_name):
attrs = {'a_id': Required(int)}
cls = EntityMeta(class_name, (db.Entity,), attrs)
return cls
b1 = load_tables(db, 's1', 'B1')
b2 = load_tables(db, 's2', 'B2')
In your example class A has a relationship to class B. It should be relationship to a single class, so you cannot define it this way. You probably neet to use explicit id value instead and make joins manually
stsouko
Thank you very much!
stsouko
I spent an hour reading the source. but I did not understand how EntityMeta work
stsouko
q2. is it possible to declare Entity in common way as class in load_tables? I use mixins in Entities.
Alexander
I think it is hard to declare it as a class, because class cannot take class name from the variable, and we cannot use the same name for different entities.
But if referential integrity is not important, you can define multiple databases, one database for each schema, and have the same entity in each of these databases. This way you can define entity as a class:
def define_entities(db):
class B(db.Entity):
a_id = Required(int)
db = Database()
class A(db.Entity):
pass
db1 = Database()
define_entities(db1)
db2 = Database()
define_entities(db2)
Alexander
You can then use multiple databases in the same db_session. You cannot mix objects from the different databases inside the same select, but you can explicitly specify id value if you know it
stsouko
Thank you!
Alan
Hi All - I'm new to PonyORM, and an indermediate pythoner (mostly jupyter notebook work - which will explain the basicness of this question), but I wanted to set up my entities and DB connections in a separate file that I can just reference from other scripts. This is eluding me right now as I tried to do all the db creation and binding in the init method of another class. The issue is obviously that then the entity classes can't access it. Any suggestions?
Micaiah
Can you show us your DB code? Either pasted here or in something like pastebn
Alan
just starting out with something for the NCAA tournament, but this is what I have right now with the obviously failing init in place -
Alan
from pony.orm import *
class DataStruct(object):
def __init__(self):
db = Database()
db.bind('sqlite', 'BracketDB.sqlite', create_db = True)
db.generate_mapping(create_tables = True)
sql_debug(True)
class Team(db.Entity):
name = Required(str)
espn_id = PrimaryKey(int)
players = Set('Player')
games = Set('Game')
class Game(db.Entity):
home = Required(Team)
away = Required(Team)
date = Required(datetime)
home_score = Required(int)
away_score = Required(int)
stats = Set('GameStats')
class Player(db.Entity):
espn_id = PrimaryKey(int)
name = Required(str)
year = Required(int)
Micaiah
In this code db.Entity only exists within the scope of DataStruct's init method
Micaiah
Take the __init__ code and move it to the module scope and it should work
Micaiah
from pony.orm import *
db = Database()
sql_debug(True)
class Team(db.Entity):
name = Required(str)
espn_id = PrimaryKey(int)
players = Set('Player')
games = Set('Game')
class Game(db.Entity):
home = Required(Team)
away = Required(Team)
date = Required(datetime)
home_score = Required(int)
away_score = Required(int)
stats = Set('GameStats')
class Player(db.Entity):
espn_id = PrimaryKey(int)
name = Required(str)
year = Required(int)
db.bind('sqlite', 'BracketDB.sqlite', create_db = True)
db.generate_mapping(create_tables = True)
Micaiah
actually you want to bind and generate after the Entities have been defined
Alan
got it, thanks - I'm not great at organizing code. Appreciate the help, really enjoying the way this package works so far
Micaiah
its a great package
Micaiah
Micaiah
the name attribute is unique, but the except clause isn't catching the error
Micaiah
it isn't making duplicates, but it is replying "Made: whatever" succesfully even though it isn't
Lucky
Uh, what's that bot?
(also whats `await`?)
Micaiah
(await is python 3.5's asyncio syntax)
Micaiah
The bot is for playing DnD on discord
Micaiah
kinda
Lucky
oh cool
Micaiah
Why doesn't the try except work
Lucky
never got any good introduction to await. how did you start?
Micaiah
reading David Beazley's post
Micaiah
and then this bot
Micaiah
its using discord.py, i think its a good itnro
Micaiah
intro*
Micaiah
since you are already comfortable with Pony and gen Python
Romet
you mean introduction to asyncio
Romet
should probably be searching for that rather than await
Micaiah
yeah
Lucky
ah, thanks. will have a look tomorrow
Micaiah
I think async/await is better than the @coroutine way
Romet
anyway it's a state machine faking being threading
Lucky
Alan
Micaiah - does your try except work without using async? Is it an issue with that or either way?
Micaiah
it needs async for the framework to work, and the rest of my orm calls work
Micaiah
Alan
Hm.. That's odd. Sorry, no idea. Any reason you're using with over the decorator
Micaiah
Yeah I couldn't get the decorator working with the @ls.command() decorator
Micaiah
hmmm, i still don't know why it isn't catching the exception
Micaiah
the exception shows up in my console
Micaiah
but in discord is says it worked
Alexander
Why doesn't the try except work
In Python, context managers inside generator functions cannot catch exceptions which were thrown into a generator from the outside. If you use an async function, you need to use @db_session as a decorator: https://docs.ponyorm.com/transactions.html#using-db-session-with-generator-functions
Lucky
Micaiah
BEast
Hi, guys.
Is it possible to use desc for lambda expression inside order_by?
Like "select((f1.name, f1.price) for f1 in Food).order_by(desc(lambda n, p: n))". Or "...desc(lambda: f1.name)...". The result is the same for both versions.
And it differs from "select((f1.name, f1.price) for f1 in Food).order_by(desc(1))".
Am I not getting something?
Artur Rakhmatulin
Hi! I recently found similar in the doc on site
Alexander
Hi @bassbeast, yes, it is vald to use desc inside lambda, but not the other way around. That is, instead of
select((f1.name, f1.price) for f1 in Food).order_by(desc(lambda: f1.name))
you should write
select((f1.name, f1.price) for f1 in Food).order_by(lambda: desc(f1.name))
Alexander
This document doesn't explains how to work with errors...
Maybe we need to add something about exceptions, but if a programmer wrap an async function with @db_session decorator then from the programmer's point of view the handling of errors should look the same as usual, he just need to wrap some lines of code with try..except block.
And if somebody tries to write async code using with db_session context manager instead of @db_session decorator, it just will not work, because in Python context managers cannot catch the event of generator suspending.