Hi,
You're quite right, the join was the tricky bit at first. Basically I
construct an outer join over all the 'dynamic' extension classes.
Here's an extract:
def _get_selectable(self):
j = None
for key, val in HasTraitsORM._decl_class_registry.iteritems():
if not val.__table__.exists():
continue
fks = val.__table__.foreign_keys
if Security.id not in [fk.column for fk in fks]:
continue
if j != None:
j = j.outerjoin(val.__table__)
else:
j = Security.__table__.outerjoin(val.__table__)
return j
It iterates over all known mapped classes, then constructs the outer
join only with those that have a Security.id foreign key constraint.
The returned join j then gets used during queries as such:
q = sess.query(Security).select_from(j)
The 'dynamically' added classes look something like this:
class SMAFields(SecurityFields):
sma10 = Float(sqldb=True)
def _get_sma10(self):
## some algo ###
return res
That code just resides in some text editor provided for the user where
he can change it, add new class etc. Then from within the main app I
use exec to compile it. The base class sets up the mapping, foreign
keys, creates the table and also adds the sma10 column to the Security
class. Which is why I can then:
data = q.filter(Security.sma10 >= 5)[:]
So even though the sma10 column isn't on the Security table itself,
through the foreign key constraint and the outer join, it behaves as
one would expect.
And the query only returns Security instances because I use
sess.query(Security), without any of the other added classes.
That all works quite well. The problems I'm having right now:
1. figuring out what the best practice is for working with data using
multiple threads
-> only have one session in the gui thread? other threads call
commit on this session using a lock?
-> expunge instances from gui sess before working on then, then
commit changes in new session? then add them back to gui's session?
2. Creation of SMAFields records if they don't exist. Right now I'm
just creating them by hand. Though automatic creation when loading a
Security would be nice.
-> tried with orm.reconstruct decorator on Security class, doesn't
seem to work.
Maybe a bit too complicated for what it achieves, but the ability to
define new fields with custom algorithms on the fly can be quite
useful for users.
--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups
"sqlalchemy" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/sqlalchemy?hl=en
-~----------~----~----~----~------~----~------~--~---