[sqlalchemy] using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Faheem Mitha


Hi,

I'm using scoped_session with PostgreSQL to run multiple threads, each 
thread creating a table. However, I'm getting some pretty weird and 
inconsistent errors (segfaults from Python with some very peculiar 
errors), and I was wondering if my usage was at fault.


The program has a serial bit, and a parallel bit, and currently I'm doing 
something like this. For the serial bit I do


db = create_engine(dbstring)
Session = sessionmaker()
session = Session(bind=db)

and then later I do

session.close()

db = create_engine(self.dbstring)
Session = scoped_session(sessionmaker())
Session.configure(bind=db)

Looking at this is seems likely that is would be better to just use 
scoped_session everywhere, that is, just start with


db = create_engine(self.dbstring)
Session = scoped_session(sessionmaker())
Session.configure(bind=db)
[proceed with using Session in serial mode and eventually use it in 
parallel mode too]


I'm basically writing to confirm that it is Ok to use scoped_session in 
this way. The way I'm doing it looks a little dodgy. I don't know if this 
is really the cause of my problem - just clutching at straws here. Thanks 
in advance. Please CC me on any reply.


  Regards, Faheem

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] mixed up relationships

2010-08-12 Thread Bleve
I'm using SQLAlchemy 0.6.3 on Python 2.6 (win32)

I have a class, Efforts, which has many splits (time and distance and
some other fluff), so for each training effort, there can be one or
more splits.  It has a few other relationships as well, but this is
the important one, or at least, the one I'm stuck on at the moment!

The definition in my script :

class Efforts(Base):
__tablename__ = 'efforts'

id = Column(Integer, primary_key = True)
effortTypeId = Column(Integer, ForeignKey(effortTypes.id),
nullable=False)
riderId = Column(Integer, ForeignKey(riders.id), nullable=False)
sessionId = Column(Integer, ForeignKey(trainingSessions.id),
nullable=False)
.
# stuff trimmed to save space
.

splits = relationship(Splits, backref='efforts',
order_by=Splits.sequenceNumber)
rider = relationship(Riders, backref='efforts',
order_by=Riders.id)
session = relationship(TrainingSessions, backref='efforts',
order_by= TrainingSessions.id)


def __init__(self, effortTypeId, riderId, sessionId, distance,
time, maxpower, fiveSecPower, \
maxTorque, startTime, temperature, pressure, humidity, windSpeed,
comments, timingAccuracy, \
gearInches, seated, standingStartType, startingSpeed, startingLeg,
riderWeight, bikeWeight, \
extraWeight, borgRPE):
self.effortTypeId = effortTypeId
self.riderId = riderId
self.sessionId = sessionId

   # stuff trimmed ...


and the 'splits' definition :

class Splits(Base):
__tablename__ = 'splits'


id = Column(Integer, primary_key = True)
effort = Column(Integer, ForeignKey(efforts.id), nullable=False)
sequenceNumber = Column(Integer, nullable=False, default = 1)
distance = Column(Float, nullable=False)
time = Column(Float, nullable=False)
timingAccuracy = Column(Float, default = 0.1)

def __init__(self, effort, sequenceNumber, distance, time,
timingAccuracy):
self.effort = effort
self.sequenceNumber = sequenceNumber
self.distance = distance
self.time = time
self.timingAccuracy = timingAccuracy



I've stuffed something up, because when I create an 'effort' :


   trainingEffort = stDataClasses.Efforts(
effortTypeId = ChosenEffortId,\
riderId = self.rider.id,\
sessionId = self.thisSession.id,\
.
.
.
)
print trainingEffort
print splits in trainingEffort :, trainingEffort.Splits



I should, I think, see a null array when I ask for
trainingEffort.Splits, but instead I see this :

AttributeError: 'Efforts' object has no attribue 'Splits'

Can anyone here untangle my mess?  My python skill level is still very
much a novice, I've read the SQLAlchemy doco for the ORM but I think
something's just not sinking in.

Thank you for any pointers in the right direction!

Carl


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Faheem Mitha


Addendum: the types of error I'm seeing includes SQLA trying to execute 
notices from the PG server eg. one of the tracebacks I'm seeing is:


#0  PyObject_Malloc (nbytes=86) at ../Objects/obmalloc.c:756
#1  0x00455eb5 in PyString_FromString (str=0x2de0ece0 WARNING:
there is no transaction in progress\n)
at ../Objects/stringobject.c:139

This smells like memory being overwritten. Any idea what might be causing 
this?


Another possibility is that my usage of scoped_session is wrong. I can't 
find any explicit examples of usage in the official documentation, so this 
was partly guesswork on my part. Here is a sketch of my usage. The model 
I'm using is a thread pool, which lines up n jobs in a queue, and has a 
pool of k threads executing them. The problems seem to occur when n is too 
large.


Session = scoped_session(sessionmaker())
Session.configure(bind=db)
pool = ThreadPool(Session, self.jobs)
ids = self.get_idlink_ids(Session)
for i in ids:
pool.add_task(self.load_geno_table_from_file, Session, i)
pool.start()

where load_geno_table_from_file is

def load_geno_table_from_file(self, session, i):
session.execute(ALTER TABLE %s.geno%s SET ( autovacuum_enabled = false 
);%(self.schema, i))
self.drop_geno_table_constraints(session, 'geno%s'%i)
self.copy_data_to_geno_table(session, 'geno%s'%i, 'tmp/geno%s'%i)
self.restore_geno_table_constraints(session, 'geno%s'%i)
session.execute(ALTER TABLE %s.geno%s SET ( autovacuum_enabled = true 
);%(self.schema, i))

and add_task is

def add_task(self, func, *args, **kargs):
Add a task to the queue
self.queue.put((func, args, kargs))

So, Session is passed to load_geno_table_from_file, which executes inside 
each thread. Is that Ok? I'm adding the rest of the thread code below for 
reference.

  Regards, Faheem

***
import Queue, threading, urllib2, time

class Worker(threading.Thread):
Thread executing tasks from a given tasks queue
def __init__(self, session, queue, num):
threading.Thread.__init__(self)
self.num = num
self.queue = queue
self.setDaemon(True)
self.session = session

def run(self):
import traceback
while True:
func, args, kargs = self.queue.get()
try:
func(*args, **kargs)
except:
traceback.print_exc()
self.queue.task_done()

class ThreadPool:
Pool of threads consuming tasks from a queue
def __init__(self, session, num_threads):
from geno import Geno_Shard
self.queue = Queue.Queue()
self.workerlist = []
self.num = num_threads
self.session = session
for i in range(num_threads):
self.workerlist.append(Worker(session, self.queue, i))

def add_task(self, func, *args, **kargs):
Add a task to the queue
self.queue.put((func, args, kargs))

def start(self):
for w in self.workerlist:
w.start()

def wait_completion(self):
Wait for completion of all the tasks in the queue
self.queue.join()



On Thu, 12 Aug 2010, Faheem Mitha wrote:



Hi,

I'm using scoped_session with PostgreSQL to run multiple threads, each thread 
creating a table. However, I'm getting some pretty weird and inconsistent 
errors (segfaults from Python with some very peculiar errors), and I was 
wondering if my usage was at fault.


The program has a serial bit, and a parallel bit, and currently I'm doing 
something like this. For the serial bit I do


db = create_engine(dbstring)
Session = sessionmaker()
session = Session(bind=db)

and then later I do

session.close()

db = create_engine(self.dbstring)
Session = scoped_session(sessionmaker())
Session.configure(bind=db)

Looking at this is seems likely that is would be better to just use 
scoped_session everywhere, that is, just start with


db = create_engine(self.dbstring)
Session = scoped_session(sessionmaker())
Session.configure(bind=db)
[proceed with using Session in serial mode and eventually use it in parallel 
mode too]


I'm basically writing to confirm that it is Ok to use scoped_session in this 
way. The way I'm doing it looks a little dodgy. I don't know if this is 
really the cause of my problem - just clutching at straws here. Thanks in 
advance. Please CC me on any reply.


 Regards, Faheem




--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Multiple Sessions

2010-08-12 Thread Erich Eder
I've found a strange behaviour when using multiple sessions: A
committed change to an object in one session does not get reflected in
the other session, even after a session.expire_all() (or expire() or
refresh() on the object. In fact, even an explicit query does not
retrieve the changed data. I'm using MySQL. Further investigation
showed that it happens only with InnoDB. Using MyISAM produces the
expected results. Looks like a caching issue with InnoDB.

Here is some test code:

from sqlalchemy import create_engine, Table, Column, Integer
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base=declarative_base()

class A(Base):
__tablename__=a
__table_args__ = {'mysql_engine':'InnoDB'}

id = Column(Integer, primary_key=True)
data = Column(Integer)

engine = create_engine('mysql://localhost/test')
Base.metadata.bind = engine
Base.metadata.drop_all()
Base.metadata.create_all()

Session = sessionmaker(bind=engine)
session1 = Session()
session2 = Session()

a1 = A()
a1.id = 1
a1.data = 123

session1.add(a1)
session1.commit()

print a1.data   # trigger query of a1.data

a2 = session2.query(A).one()

print a1,a2 # to see that a1 and a2 are different objects
print a2.data

a2.data = 999
session2.commit()

print a1.data: , a1.data
print session1.query(A.data): , session1.query(A.data).one()[0]
print session2.query(A.data): , session2.query(A.data).one()[0]

print session1.expire_all()
session1.expire_all()

print a1.data: , a1.data
print session1.query(A.data): , session1.query(A.data).one()[0]
print session2.query(A.data): , session2.query(A.data).one()[0]


The output is:
123
a1.data:  123
session1.query(A.data):  123
session2.query(A.data):  999
session1.expire_all()
a1.data:  123
session1.query(A.data):  123
session2.query(A.data):  999


When commenting out the __table_args__ line in order to use MyISAM,
the output is what one would expect:
123
a1.data:  123
session1.query(A.data):  999
session2.query(A.data):  999
session1.expire_all()
a1.data:  999
session1.query(A.data):  999
session2.query(A.data):  999


Any idea?

Thanks,
Erich

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: mixed up relationships

2010-08-12 Thread Sven A. Schmidt
Carl,

the formatting got a bit messed up but if I read your definition
correctly you defined the relation as 'splits'. So you'd want to write
trainingEffor.splits (lower case 's' in splits).

-sas

On Aug 12, 9:20 am, Bleve carl.i.bre...@gmail.com wrote:
 I'm using SQLAlchemy 0.6.3 on Python 2.6 (win32)

 I have a class, Efforts, which has many splits (time and distance and
 some other fluff), so for each training effort, there can be one or
 more splits.  It has a few other relationships as well, but this is
 the important one, or at least, the one I'm stuck on at the moment!

 The definition in my script :

 class Efforts(Base):
     __tablename__ = 'efforts'

     id = Column(Integer, primary_key = True)
     effortTypeId = Column(Integer, ForeignKey(effortTypes.id),
 nullable=False)
     riderId = Column(Integer, ForeignKey(riders.id), nullable=False)
     sessionId = Column(Integer, ForeignKey(trainingSessions.id),
 nullable=False)
     .
     # stuff trimmed to save space
     .

     splits = relationship(Splits, backref='efforts',
 order_by=Splits.sequenceNumber)
     rider = relationship(Riders, backref='efforts',
 order_by=Riders.id)
     session = relationship(TrainingSessions, backref='efforts',
 order_by= TrainingSessions.id)

     def __init__(self, effortTypeId, riderId, sessionId, distance,
 time, maxpower, fiveSecPower, \
     maxTorque, startTime, temperature, pressure, humidity, windSpeed,
 comments, timingAccuracy, \
     gearInches, seated, standingStartType, startingSpeed, startingLeg,
 riderWeight, bikeWeight, \
     extraWeight, borgRPE):
         self.effortTypeId = effortTypeId
         self.riderId = riderId
         self.sessionId = sessionId

        # stuff trimmed ...

 and the 'splits' definition :

 class Splits(Base):
     __tablename__ = 'splits'

     id = Column(Integer, primary_key = True)
     effort = Column(Integer, ForeignKey(efforts.id), nullable=False)
     sequenceNumber = Column(Integer, nullable=False, default = 1)
     distance = Column(Float, nullable=False)
     time = Column(Float, nullable=False)
     timingAccuracy = Column(Float, default = 0.1)

     def __init__(self, effort, sequenceNumber, distance, time,
 timingAccuracy):
         self.effort = effort
         self.sequenceNumber = sequenceNumber
         self.distance = distance
         self.time = time
         self.timingAccuracy = timingAccuracy

 I've stuffed something up, because when I create an 'effort' :

        trainingEffort = stDataClasses.Efforts(
                         effortTypeId = ChosenEffortId,\
                         riderId = self.rider.id,\
                         sessionId = self.thisSession.id,\
                         .
                         .
                         .
                         )
         print trainingEffort
         print splits in trainingEffort :, trainingEffort.Splits

 I should, I think, see a null array when I ask for
 trainingEffort.Splits, but instead I see this :

 AttributeError: 'Efforts' object has no attribue 'Splits'

 Can anyone here untangle my mess?  My python skill level is still very
 much a novice, I've read the SQLAlchemy doco for the ORM but I think
 something's just not sinking in.

 Thank you for any pointers in the right direction!

 Carl

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Faheem Mitha


Another reply to my own message, sorry.

Another thing I might be doing wrong is my usage of MetaData.
The code I have looks like

   db = create_engine(self.dbstring)
   meta = self.table_dict['metadata']
   meta.bind = db
   meta.create_all()
   Session = scoped_session(sessionmaker())
   Session.configure(bind=db)
   pool = ThreadPool(Session, self.jobs)
   ids = self.get_idlink_ids(Session)
   for i in ids:
   pool.add_task(self.load_geno_table_from_file, Session, i)
   pool.start()

Perhaps creation of this metadata instance is not thread-safe? I found 
reference to a ThreadLocalMetaData. Would it better to use that instead?


   Regards, Faheem.

On Thu, 12 Aug 2010, Faheem Mitha wrote:



Addendum: the types of error I'm seeing includes SQLA trying to execute 
notices from the PG server eg. one of the tracebacks I'm seeing is:


#0  PyObject_Malloc (nbytes=86) at ../Objects/obmalloc.c:756
#1  0x00455eb5 in PyString_FromString (str=0x2de0ece0 WARNING:
there is no transaction in progress\n)
   at ../Objects/stringobject.c:139

This smells like memory being overwritten. Any idea what might be causing 
this?


Another possibility is that my usage of scoped_session is wrong. I can't find 
any explicit examples of usage in the official documentation, so this was 
partly guesswork on my part. Here is a sketch of my usage. The model I'm 
using is a thread pool, which lines up n jobs in a queue, and has a pool of k 
threads executing them. The problems seem to occur when n is too large.


Session = scoped_session(sessionmaker())
Session.configure(bind=db)
pool = ThreadPool(Session, self.jobs)
ids = self.get_idlink_ids(Session)
for i in ids:
   pool.add_task(self.load_geno_table_from_file, Session, i)
pool.start()

where load_geno_table_from_file is

def load_geno_table_from_file(self, session, i):
   session.execute(ALTER TABLE %s.geno%s SET ( autovacuum_enabled = 
false );%(self.schema, i))

   self.drop_geno_table_constraints(session, 'geno%s'%i)
   self.copy_data_to_geno_table(session, 'geno%s'%i, 'tmp/geno%s'%i)
   self.restore_geno_table_constraints(session, 'geno%s'%i)
   session.execute(ALTER TABLE %s.geno%s SET ( autovacuum_enabled = 
true );%(self.schema, i))


and add_task is

def add_task(self, func, *args, **kargs):
   Add a task to the queue
   self.queue.put((func, args, kargs))

So, Session is passed to load_geno_table_from_file, which executes inside 
each thread. Is that Ok? I'm adding the rest of the thread code below for 
reference.

 Regards, Faheem

***
import Queue, threading, urllib2, time

class Worker(threading.Thread):
   Thread executing tasks from a given tasks queue
   def __init__(self, session, queue, num):
   threading.Thread.__init__(self)
   self.num = num
   self.queue = queue
   self.setDaemon(True)
   self.session = session

   def run(self):
   import traceback
   while True:
   func, args, kargs = self.queue.get()
   try:
   func(*args, **kargs)
   except:
   traceback.print_exc()
   self.queue.task_done()

class ThreadPool:
   Pool of threads consuming tasks from a queue
   def __init__(self, session, num_threads):
   from geno import Geno_Shard
   self.queue = Queue.Queue()
   self.workerlist = []
   self.num = num_threads
   self.session = session
   for i in range(num_threads):
   self.workerlist.append(Worker(session, self.queue, i))

   def add_task(self, func, *args, **kargs):
   Add a task to the queue
   self.queue.put((func, args, kargs))

   def start(self):
   for w in self.workerlist:
   w.start()

   def wait_completion(self):
   Wait for completion of all the tasks in the queue
   self.queue.join()



On Thu, 12 Aug 2010, Faheem Mitha wrote:



Hi,

I'm using scoped_session with PostgreSQL to run multiple threads, each 
thread creating a table. However, I'm getting some pretty weird and 
inconsistent errors (segfaults from Python with some very peculiar errors), 
and I was wondering if my usage was at fault.


The program has a serial bit, and a parallel bit, and currently I'm doing 
something like this. For the serial bit I do


db = create_engine(dbstring)
Session = sessionmaker()
session = Session(bind=db)

and then later I do

session.close()

db = create_engine(self.dbstring)
Session = scoped_session(sessionmaker())
Session.configure(bind=db)

Looking at this is seems likely that is would be better to just use 
scoped_session everywhere, that is, just start with


db = create_engine(self.dbstring)
Session = scoped_session(sessionmaker())
Session.configure(bind=db)
[proceed with using Session in serial mode and eventually use it in 
parallel mode too]


I'm basically writing to confirm that it is Ok to use 

Re: [sqlalchemy] Multiple Sessions

2010-08-12 Thread Michael Bayer

On Aug 12, 2010, at 7:36 AM, Erich Eder wrote:

 I've found a strange behaviour when using multiple sessions: A
 committed change to an object in one session does not get reflected in
 the other session, even after a session.expire_all() (or expire() or
 refresh() on the object. In fact, even an explicit query does not
 retrieve the changed data. I'm using MySQL. Further investigation
 showed that it happens only with InnoDB. Using MyISAM produces the
 expected results. Looks like a caching issue with InnoDB.

its not caching, its transaction isolation, which is why expire_all() is not 
the issue here (and why expire_all() is not really needed by itself with 
autocommit=False - rollback() and commit() handle it).   at the end, session1 
is still open in its second transaction which has loaded a1.data as 123.

http://dev.mysql.com/doc/refman/5.0/en/innodb-consistent-read.html


 
 Here is some test code:
 
 from sqlalchemy import create_engine, Table, Column, Integer
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy.ext.declarative import declarative_base
 
 Base=declarative_base()
 
 class A(Base):
__tablename__=a
__table_args__ = {'mysql_engine':'InnoDB'}
 
id = Column(Integer, primary_key=True)
data = Column(Integer)
 
 engine = create_engine('mysql://localhost/test')
 Base.metadata.bind = engine
 Base.metadata.drop_all()
 Base.metadata.create_all()
 
 Session = sessionmaker(bind=engine)
 session1 = Session()
 session2 = Session()
 
 a1 = A()
 a1.id = 1
 a1.data = 123
 
 session1.add(a1)
 session1.commit()
 
 print a1.data   # trigger query of a1.data
 
 a2 = session2.query(A).one()
 
 print a1,a2 # to see that a1 and a2 are different objects
 print a2.data
 
 a2.data = 999
 session2.commit()
 
 print a1.data: , a1.data
 print session1.query(A.data): , session1.query(A.data).one()[0]
 print session2.query(A.data): , session2.query(A.data).one()[0]
 
 print session1.expire_all()
 session1.expire_all()
 
 print a1.data: , a1.data
 print session1.query(A.data): , session1.query(A.data).one()[0]
 print session2.query(A.data): , session2.query(A.data).one()[0]
 
 
 The output is:
 123
 a1.data:  123
 session1.query(A.data):  123
 session2.query(A.data):  999
 session1.expire_all()
 a1.data:  123
 session1.query(A.data):  123
 session2.query(A.data):  999
 
 
 When commenting out the __table_args__ line in order to use MyISAM,
 the output is what one would expect:
 123
 a1.data:  123
 session1.query(A.data):  999
 session2.query(A.data):  999
 session1.expire_all()
 a1.data:  999
 session1.query(A.data):  999
 session2.query(A.data):  999
 
 
 Any idea?
 
 Thanks,
 Erich
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/sqlalchemy?hl=en.
 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: mixed up relationships

2010-08-12 Thread Carl Brewer

On 12/08/2010 10:03 PM, Sven A. Schmidt wrote:

Carl,

the formatting got a bit messed up but if I read your definition
correctly you defined the relation as 'splits'. So you'd want to write
trainingEffor.splits (lower case 's' in splits).


heh!  Case sensitivity bites!

Thank you

Carl



--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Michael Bayer

On Aug 12, 2010, at 5:10 AM, Faheem Mitha wrote:

 
 Hi,
 
 I'm using scoped_session with PostgreSQL to run multiple threads, each thread 
 creating a table.

Its generally a poor application practice for an application to need new 
permanent tables on the fly.   I think reddit's application might do this, but 
its considered poor design.  Database schemas are supposed to be fixed.


 However, I'm getting some pretty weird and inconsistent errors (segfaults 
 from Python with some very peculiar errors), and I was wondering if my usage 
 was at fault.
 
 The program has a serial bit, and a parallel bit, and currently I'm doing 
 something like this. For the serial bit I do
 
 db = create_engine(dbstring)
 Session = sessionmaker()
 session = Session(bind=db)
 
 and then later I do
 
 session.close()
 
 db = create_engine(self.dbstring)
 Session = scoped_session(sessionmaker())
 Session.configure(bind=db)
 
 Looking at this is seems likely that is would be better to just use 
 scoped_session everywhere, that is, just start with
 
 db = create_engine(self.dbstring)
 Session = scoped_session(sessionmaker())
 Session.configure(bind=db)
 [proceed with using Session in serial mode and eventually use it in parallel 
 mode too]
 
 I'm basically writing to confirm that it is Ok to use scoped_session in this 
 way. The way I'm doing it looks a little dodgy. I don't know if this is 
 really the cause of my problem - just clutching at straws here. Thanks in 
 advance. Please CC me on any reply.

you can make as many scoped_sessions, metadatas, etc. as you want, none of that 
would cause a segfault.They are just Python objects. Its only if you 
share a psycopg2 connection between threads and have different threads hammer 
on it simultaneously that there would be issues like that.If you have a 
single session, and share that among threads who access it concurrently, this 
will produce that result. There should be no need to guess about it.  If 
multiple threads are hitting the session you have above, then that's a likely 
cause of your issue.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Faheem Mitha
On Thu, 12 Aug 2010 08:47:33 -0400, Michael Bayer mike...@zzzcomputing.com 
wrote:

 On Aug 12, 2010, at 5:10 AM, Faheem Mitha wrote:

 
 Hi,
 
 I'm using scoped_session with PostgreSQL to run multiple threads, each 
 thread creating a table.

 Its generally a poor application practice for an application to need
 new permanent tables on the fly.  I think reddit's application might
 do this, but its considered poor design.  Database schemas are
 supposed to be fixed.

I'm not sure what you mean by on-the-fly. The app is creating the
tables for later use. It is parallelizing the table creation for
performance reasons - there are a lot of tables.

 However, I'm getting some pretty weird and inconsistent errors
 (segfaults from Python with some very peculiar errors), and I was
 wondering if my usage was at fault.

 The program has a serial bit, and a parallel bit, and currently I'm doing 
 something like this. For the serial bit I do
 
 db = create_engine(dbstring)
 Session = sessionmaker()
 session = Session(bind=db)
 
 and then later I do
 
 session.close()
 
 db = create_engine(self.dbstring)
 Session = scoped_session(sessionmaker())
 Session.configure(bind=db)

 Looking at this is seems likely that is would be better to just use 
 scoped_session everywhere, that is, just start with

 db = create_engine(self.dbstring)
 Session = scoped_session(sessionmaker())
 Session.configure(bind=db)
 [proceed with using Session in serial mode and eventually use it in parallel 
 mode too]

 I'm basically writing to confirm that it is Ok to use
   scoped_session in this way. The way I'm doing it looks a little
   dodgy. I don't know if this is really the cause of my problem -
   just clutching at straws here. Thanks in advance. Please CC me on
   any reply

 you can make as many scoped_sessions, metadatas, etc. as you want,
  none of that would cause a segfault.  They are just Python
  objects. Its only if you share a psycopg2 connection between threads
  and have different threads hammer on it simultaneously that there
  would be issues like that.  If you have a single session, and share
  that among threads who access it concurrently, this will produce
  that result.  There should be no need to guess about it.  If
  multiple threads are hitting the session you have above, then that's
  a likely cause of your issue.

Hi Mike,

Thanks for the response, but I don't follow.

When you say multiple threads are hitting the session you have
above, which session are you referring to?  There is more than one
object above that could be called a session. Ie.

Session1 in Session1 = sessionmaker()
session1 in session1 = Session1(bind=db)
Session2 in Session2 = scoped_session(sessionmaker())

Let me try to ask a precise question. If I do

Session = scoped_session(sessionmaker())

then is it ok for this Session object to be be passed around
between multiple threads and used directly as in

Session.commit()

Does this correspond to a single psycopyg2 connection? If it does, and
this usage is wrong, should I be creating separate sessions within
each thread like

session = Session()

and then doing

session.commit()

within each thread? Or something else? My usage is based on examples
online.

My later posts have more details, along with healthy amounts of
confusion. I apologise for my cluelessness, sorry.

Regards, Faheem



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Michael Bayer

On Aug 12, 2010, at 9:25 AM, Faheem Mitha wrote:

 
 Hi Mike,
 
 Thanks for the response, but I don't follow.
 
 When you say multiple threads are hitting the session you have
 above, which session are you referring to?  There is more than one
 object above that could be called a session. Ie.


I don't actually know, it would require that I have a full install of your 
application for me to run and step through with a debugger to fully understand 
what it's doing. All I can say from here is that the errors you have 
suggest concurrent access to a single psycopg2 connection resource, and that a 
single Session references a single connection when in use.   A MetaData object 
does not, nor does an Engine - only a Session.If you remove all threading 
from your application and the errors go away, then you know you're accessing 
some resource illegally.


 
 Session1 in Session1 = sessionmaker()
 session1 in session1 = Session1(bind=db)
 Session2 in Session2 = scoped_session(sessionmaker())
 
 Let me try to ask a precise question. If I do
 
 Session = scoped_session(sessionmaker())
 
 then is it ok for this Session object to be be passed around
 between multiple threads and used directly as in
 
 Session.commit()
 
 Does this correspond to a single psycopyg2 connection? If it does, and
 this usage is wrong, should I be creating separate sessions within
 each thread like

That's a scoped_session, which is threadsafe.   Everything you call upon it 
will acquire a Session object from a thread local context, and commit() is 
called on that (for information on thread locals, see 
http://docs.python.org/library/threading.html#threading.local.   

If you pass a scoped_session from one thread to another, and the second thread 
calls commit(), the second thread is not affecting the transaction begun by the 
first.   They are two separate transactions.



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Faheem Mitha
On Thu, 12 Aug 2010 09:44:04 -0400, Michael Bayer mike...@zzzcomputing.com 
wrote:

 On Aug 12, 2010, at 9:25 AM, Faheem Mitha wrote:

 
 Hi Mike,
 
 Thanks for the response, but I don't follow.
 
 When you say multiple threads are hitting the session you have
 above, which session are you referring to?  There is more than one
 object above that could be called a session. Ie.


 I don't actually know, it would require that I have a full install
  of your application for me to run and step through with a debugger
  to fully understand what it's doing.  All I can say from here is
  that the errors you have suggest concurrent access to a single
  psycopg2 connection resource, and that a single Session references a
  single connection when in use.  A MetaData object does not, nor does
  an Engine - only a Session.  If you remove all threading from your
  application and the errors go away, then you know you're accessing
  some resource illegally.

Yes, I see. Yes, the error does not show up unless I run multiple
threads, and I agree with your interpretation.

If MetaData is threadsafe, then using ThreadLocalMetaData is not
necessary?

 Session1 in Session1 = sessionmaker()
 session1 in session1 = Session1(bind=db)
 Session2 in Session2 = scoped_session(sessionmaker())
 
 Let me try to ask a precise question. If I do
 
 Session = scoped_session(sessionmaker())
 
 then is it ok for this Session object to be be passed around
 between multiple threads and used directly as in
 
 Session.commit()
 
 Does this correspond to a single psycopyg2 connection? If it does, and
 this usage is wrong, should I be creating separate sessions within
 each thread like

 That's a scoped_session, which is threadsafe.  Everything you call
 upon it will acquire a Session object from a thread local context,
 and commit() is called on that (for information on thread locals,
 see http://docs.python.org/library/threading.html#threading.local.

 If you pass a scoped_session from one thread to another, and the
 second thread calls commit(), the second thread is not affecting the
 transaction begun by the first.  They are two separate transactions.

Ok. Thanks for the confirmation. So, if I was to use scoped sessions
systematically everywhere, this problem would likely disappear. Can
you confirm that there is no reason not to use scoped sessions
everywhere, even in serial execution? Of course, if that is the case,
then I wonder why non-scoped sessions are used at all.

 Regards, Faheem.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Faheem Mitha
On Thu, 12 Aug 2010 09:44:04 -0400, Michael Bayer mike...@zzzcomputing.com 
wrote:

 On Aug 12, 2010, at 9:25 AM, Faheem Mitha wrote:

 
 Hi Mike,
 
 Thanks for the response, but I don't follow.
 
 When you say multiple threads are hitting the session you have
 above, which session are you referring to?  There is more than one
 object above that could be called a session. Ie.


 I don't actually know, it would require that I have a full install of your 
 application for me to run and step through with a debugger to fully 
 understand what it's doing. All I can say from here is that the errors 
 you have suggest concurrent access to a single psycopg2 connection resource, 
 and that a single Session references a single connection when in use.   A 
 MetaData object does not, nor does an Engine - only a Session.If you 
 remove all threading from your application and the errors go away, then you 
 know you're accessing some resource illegally.


 
 Session1 in Session1 = sessionmaker()
 session1 in session1 = Session1(bind=db)
 Session2 in Session2 = scoped_session(sessionmaker())
 
 Let me try to ask a precise question. If I do
 
 Session = scoped_session(sessionmaker())
 
 then is it ok for this Session object to be be passed around
 between multiple threads and used directly as in
 
 Session.commit()
 
 Does this correspond to a single psycopyg2 connection? If it does, and
 this usage is wrong, should I be creating separate sessions within
 each thread like

 That's a scoped_session, which is threadsafe.   Everything you call upon it 
 will acquire a Session object from a thread local context, and commit() is 
 called on that (for information on thread locals, see 
 http://docs.python.org/library/threading.html#threading.local.   

 If you pass a scoped_session from one thread to another, and the second 
 thread calls commit(), the second thread is not affecting the transaction 
 begun by the first.   They are two separate transactions.




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Michael Bayer

On Aug 12, 2010, at 11:47 AM, Faheem Mitha wrote:

 On Thu, 12 Aug 2010 09:44:04 -0400, Michael Bayer mike...@zzzcomputing.com 
 wrote:
 
 On Aug 12, 2010, at 9:25 AM, Faheem Mitha wrote:
 
 
 Hi Mike,
 
 Thanks for the response, but I don't follow.
 
 When you say multiple threads are hitting the session you have
 above, which session are you referring to?  There is more than one
 object above that could be called a session. Ie.
 
 
 I don't actually know, it would require that I have a full install
  of your application for me to run and step through with a debugger
  to fully understand what it's doing.  All I can say from here is
  that the errors you have suggest concurrent access to a single
  psycopg2 connection resource, and that a single Session references a
  single connection when in use.  A MetaData object does not, nor does
  an Engine - only a Session.  If you remove all threading from your
  application and the errors go away, then you know you're accessing
  some resource illegally.
 
 Yes, I see. Yes, the error does not show up unless I run multiple
 threads, and I agree with your interpretation.
 
 If MetaData is threadsafe, then using ThreadLocalMetaData is not
 necessary?

ThreadLocalMetaData is not necessary and is not used for this purpose.

 
 Ok. Thanks for the confirmation. So, if I was to use scoped sessions
 systematically everywhere, this problem would likely disappear.

that's not necessarily true - if you share individual persistent objects among 
threads, they reference their owning session in order to load additional state. 
  If you pass objects between threads you should merge() them into the current 
thread's session first, then use that result.


 Can
 you confirm that there is no reason not to use scoped sessions
 everywhere, even in serial execution? Of course, if that is the case,
 then I wonder why non-scoped sessions are used at all.

scoped_sessions are usually the default choice for web applications since they 
desire distinct transactions and object state for individual threads.They 
are overkill and potentially confusing or inappropriate in other situations, 
however.


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: User DataType for casting

2010-08-12 Thread Kent
On Jul 30, 7:25 am, Kent k...@retailarchitects.com wrote:
 Also, I'm afraid the CAST(NULL AS VARCHAR(255)) doesn't work with
 Oracle 8, but I don't have access to Oracle 8 at the moment.  I'm
 afraid you need TO_NUMBER(NULL) or TO_CHAR(NULL), etc...



I'm wrong, CAST seems to work fine on Oracle 8i.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] How to link one table to itself?

2010-08-12 Thread Alvaro Reinoso
Hello,

I'm trying to link one table to itself. I have media groups which can
contain more media group. I created a relation many to many:

media_group_groups = Table(
media_group_groups,
metadata,
Column(groupA_id, Integer, 
ForeignKey(media_groups.id)),
Column(groupB_id, Integer, 
ForeignKey(media_groups.id))
)

class MediaGroup(rdb.Model):
Represents MediaGroup class. Conteins channels and other media
groups
rdb.metadata(metadata)
rdb.tablename(media_groups)

id = Column(id, Integer, primary_key=True)
title = Column(title, String(100))
parents = Column(parents, String(512))

channels = relationship(Channel, secondary=media_group_channels,
order_by=Channel.titleView, backref=media_groups)
mediaGroup = relationship(MediaGroup,
secondary=media_group_groups, order_by=MediaGroup.title,
backref=media_groups)

I got this error:

ArgumentError: Could not determine join condition between parent/
child tables on relationship MediaGroup.mediaGroup. Specify a
'primaryjoin' expression. If this is a many-to-many relationship,
'secondaryjoin' is needed as well.

When I create the tables I don't get any error, it's just when I add
any element to it.
Any idea???

Thanks in advance!

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Faheem Mitha
[This message has also been posted.]
On Thu, 12 Aug 2010 12:47:37 -0400, Michael Bayer mike...@zzzcomputing.com 
wrote:

 On Aug 12, 2010, at 11:47 AM, Faheem Mitha wrote:

 On Thu, 12 Aug 2010 09:44:04 -0400, Michael Bayer mike...@zzzcomputing.com 
 wrote:
 
 On Aug 12, 2010, at 9:25 AM, Faheem Mitha wrote:
 
 
 Hi Mike,

 Thanks for the response, but I don't follow.

 When you say multiple threads are hitting the session you have
 above, which session are you referring to?  There is more than one
 object above that could be called a session. Ie.

 I don't actually know, it would require that I have a full install
  of your application for me to run and step through with a debugger
  to fully understand what it's doing.  All I can say from here is
  that the errors you have suggest concurrent access to a single
  psycopg2 connection resource, and that a single Session references a
  single connection when in use.  A MetaData object does not, nor does
  an Engine - only a Session.  If you remove all threading from your
  application and the errors go away, then you know you're accessing
  some resource illegally.

 Yes, I see. Yes, the error does not show up unless I run multiple
 threads, and I agree with your interpretation.

 If MetaData is threadsafe, then using ThreadLocalMetaData is not
 necessary?

 ThreadLocalMetaData is not necessary and is not used for this purpose.

 Ok. Thanks for the confirmation. So, if I was to use scoped sessions
 systematically everywhere, this problem would likely disappear.

 that's not necessarily true - if you share individual persistent
  objects among threads, they reference their owning session in order
  to load additional state.  If you pass objects between threads you
  should merge() them into the current thread's session first, then
  use that result.

I see. That's very enlightening. Can one query such objects to
determine their owning session? Some attribute, perhaps?

 Can you confirm that there is no reason not to use scoped sessions
 everywhere, even in serial execution? Of course, if that is the
 case, then I wonder why non-scoped sessions are used at all.

 scoped_sessions are usually the default choice for web applications
  since they desire distinct transactions and object state for
  individual threads.  They are overkill and potentially confusing or
  inappropriate in other situations, however.

I'm not sure why they would be potentially confusing. What are some of
the downsides? I'd have thought that not having shared state was less
confusing.

  Regards, Faheem.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: using scoped_session in serial mode as well as parallel (multi-threaded) mode

2010-08-12 Thread Michael Bayer

On Aug 12, 2010, at 2:41 PM, Faheem Mitha wrote:

  objects among threads, they reference their owning session in order
  to load additional state.  If you pass objects between threads you
  should merge() them into the current thread's session first, then
  use that result.
 
 I see. That's very enlightening. Can one query such objects to
 determine their owning session? Some attribute, perhaps?

see http://www.sqlalchemy.org/docs/session.html#frequently-asked-questions


 
 Can you confirm that there is no reason not to use scoped sessions
 everywhere, even in serial execution? Of course, if that is the
 case, then I wonder why non-scoped sessions are used at all.
 
 scoped_sessions are usually the default choice for web applications
  since they desire distinct transactions and object state for
  individual threads.  They are overkill and potentially confusing or
  inappropriate in other situations, however.
 
 I'm not sure why they would be potentially confusing. What are some of
 the downsides? I'd have thought that not having shared state was less
 confusing.

the scoped_session is a proxy object to the real object.  It is less 
confusing for those unfamiliar with thread locals and proxy objects to deal 
with a Session directly.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: How to link one table to itself?

2010-08-12 Thread Alvaro Reinoso
I'm still working on the solution. I've found out some stuff in
internet. I guess I'm close to, but I haven't got it yet. I'm using
this for the relation:

mediaGroups = relationship(MediaGroup,
secondary=media_group_groups, order_by=MediaGroup.title,
backref='media_groups', foreign_keys =
[media_group_groups.groupA_id, media_group_groups.groupB_id],
primaryjoin = MediaGroup.id == 
media_group_groups.groupA_id,
secondaryjoin = MediaGroup.id == media_group_groups.groupB_id)

I'm playing with the parameters, but I usually get this error:

ArgumentError: Could not determine relationship direction for
primaryjoin condition 'users.id = :id_1', on relationship
User.mediaGroups. Specify the 'foreign_keys' argument to indicate
which columns on the relationship are foreign.

Thank you!

On Aug 12, 1:08 pm, Alvaro Reinoso alvrein...@gmail.com wrote:
 Hello,

 I'm trying to link one table to itself. I have media groups which can
 contain more media group. I created a relation many to many:

     media_group_groups = Table(
                         media_group_groups,
                         metadata,
                         Column(groupA_id, Integer, 
 ForeignKey(media_groups.id)),
                         Column(groupB_id, Integer, 
 ForeignKey(media_groups.id))
                 )

     class MediaGroup(rdb.Model):
         Represents MediaGroup class. Conteins channels and other media
 groups
         rdb.metadata(metadata)
         rdb.tablename(media_groups)

         id = Column(id, Integer, primary_key=True)
         title = Column(title, String(100))
         parents = Column(parents, String(512))

         channels = relationship(Channel, secondary=media_group_channels,
 order_by=Channel.titleView, backref=media_groups)
         mediaGroup = relationship(MediaGroup,
 secondary=media_group_groups, order_by=MediaGroup.title,
 backref=media_groups)

 I got this error:

 ArgumentError: Could not determine join condition between parent/
 child tables on relationship MediaGroup.mediaGroup. Specify a
 'primaryjoin' expression. If this is a many-to-many relationship,
 'secondaryjoin' is needed as well.

 When I create the tables I don't get any error, it's just when I add
 any element to it.
 Any idea???

 Thanks in advance!

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



Re: [sqlalchemy] Re: How to link one table to itself?

2010-08-12 Thread Michael Bayer

On Aug 12, 2010, at 5:09 PM, Michael Bayer wrote:

 
 On Aug 12, 2010, at 4:58 PM, Alvaro Reinoso wrote:
 
 I'm still working on the solution. I've found out some stuff in
 internet. I guess I'm close to, but I haven't got it yet. I'm using
 this for the relation:
 
  mediaGroups = relationship(MediaGroup,
 secondary=media_group_groups, order_by=MediaGroup.title,
 backref='media_groups', foreign_keys =
 [media_group_groups.groupA_id, media_group_groups.groupB_id],
  primaryjoin = MediaGroup.id == 
 media_group_groups.groupA_id,
 secondaryjoin = MediaGroup.id == media_group_groups.groupB_id)
 
 I'm playing with the parameters, but I usually get this error:
 
 ArgumentError: Could not determine relationship direction for
 primaryjoin condition 'users.id = :id_1', on relationship
 User.mediaGroups. Specify the 'foreign_keys' argument to indicate
 which columns on the relationship are foreign.
 
 media_group_groups is not available when primaryjoin is evaluated as a 
 string, nor within foreign_keys which is not necessary here since your 
 meta_group_groups already has ForeignKey objects on it, so use a non-string 
 format for primaryjoin.   i will add additional examples to the declarative 
 docs.

scratch part of that, tablenames are available in the string eval as long as 
they're from the same MetaData:

mediaGroup = relationship(MediaGroup,

secondary=media_group_groups, order_by=MediaGroup.title,
backref=media_groups, 
primaryjoin=MediaGroup.id==media_group_groups.c.groupA_id,
secondaryjoin=MediaGroup.id==media_group_groups.c.groupB_id

also the error for the exampe you have above should be 'Table' object has no 
attribute 'groupA_id'.






 
 
 
 Thank you!
 
 On Aug 12, 1:08 pm, Alvaro Reinoso alvrein...@gmail.com wrote:
 Hello,
 
 I'm trying to link one table to itself. I have media groups which can
 contain more media group. I created a relation many to many:
 
media_group_groups = Table(
media_group_groups,
metadata,
Column(groupA_id, Integer, 
 ForeignKey(media_groups.id)),
Column(groupB_id, Integer, 
 ForeignKey(media_groups.id))
)
 
class MediaGroup(rdb.Model):
Represents MediaGroup class. Conteins channels and other media
 groups
rdb.metadata(metadata)
rdb.tablename(media_groups)
 
id = Column(id, Integer, primary_key=True)
title = Column(title, String(100))
parents = Column(parents, String(512))
 
channels = relationship(Channel, secondary=media_group_channels,
 order_by=Channel.titleView, backref=media_groups)
mediaGroup = relationship(MediaGroup,
 secondary=media_group_groups, order_by=MediaGroup.title,
 backref=media_groups)
 
 I got this error:
 
 ArgumentError: Could not determine join condition between parent/
 child tables on relationship MediaGroup.mediaGroup. Specify a
 'primaryjoin' expression. If this is a many-to-many relationship,
 'secondaryjoin' is needed as well.
 
 When I create the tables I don't get any error, it's just when I add
 any element to it.
 Any idea???
 
 Thanks in advance!
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/sqlalchemy?hl=en.
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@googlegroups.com.
 To unsubscribe from this group, send email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 For more options, visit this group at 
 http://groups.google.com/group/sqlalchemy?hl=en.
 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Extending and automating the vertical dictionary paradigm

2010-08-12 Thread Choy
Hi all --

I am relatively new to sqlalchemy and am in the midst of building a
generic vertical dictionary collection base class that can be
subclassed and extended in different ways.  I began by examining the
dictlike.py and dictlike-polymorphic SQLalchemy examples and
extended them into a class factory framework using metaclasses.  This
is my first attempt at using metaclasses and class-level programming
in python.  Although my implementation works, I feel that
contributions and suggestions from all of you would substantially
improve the design.  Any comments and/or feedback would be appreciated
-- and I apologize for the somewhat complicated code.

A summary of my approach is as follows:

1) Create a method to automatically generated the database tables for
a new vertical parent class
2) Create a method to create the class types to use in mapping to the
tables
3) Instrument and connect a new class to be vertically enabled using
a metaclass method
4) Provide a simple interface that the new class can inherit via the
VerticalAttrMixin class to provide methods for accessing the key/
values in the vertical dictionary collection.

The code is provided below:
--

from datetime import datetime

from sqlalchemy import Table, Column, DateTime, String, Integer, Enum,
Boolean, Float, Sequence, ForeignKey, UniqueConstraint,
ForeignKeyConstraint
from sqlalchemy.orm import mapper, relationship
from sqlalchemy.orm.collections import attribute_mapped_collection,
MappedCollection
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.declarative import DeclarativeMeta
from sqlalchemy.orm.exc import MultipleResultsFound,NoResultFound

from sequel2.db import metadata, Base, Session, SequelDBError

ENUM_TYPE = enum
_value_types = Enum(ENUM_TYPE, bool, int, float,
name=value_type_enum)


def create_vertical_attr_tables(parent_tablename):
keys_tablename = parent_tablename + '_attr_keys'
keys_pk_seq = parent_tablename + '_key_id_seq'
keys_table = Table(keys_tablename, metadata,
   Column('id', Integer, Sequence(keys_pk_seq),
primary_key=True),
   Column('name', String(50), unique=True),
   Column('type', _value_types,
default=ENUM_TYPE),
   Column('description', String(1000)))

values_tablename = parent_tablename + '_attr_enum_values'
values_pk_seq = parent_tablename + '_enum_value_id_seq'
values_table = Table(values_tablename, metadata,
 Column('key_id', ForeignKey(keys_tablename +
'.id'), primary_key=True),
 Column('value_id', Integer,
Sequence(values_pk_seq), primary_key=True),
 Column('value', String(50), nullable=False),
 Column('description', String(1000)),
 UniqueConstraint('key_id', 'value',
name=value_unique_constraint))

attrs_tablename = parent_tablename + '_attrs'
attrs_fk = parent_tablename + '_id'
attrs_table = Table(attrs_tablename, metadata,
#Column('parent_id',
ForeignKey(parent_tablename + '.id'), primary_key=True),
Column(attrs_fk, ForeignKey(parent_tablename +
'.id'), primary_key=True),
Column('key_id', ForeignKey(keys_tablename +
'.id'), primary_key=True),
Column('enum_value_id',
ForeignKey(values_tablename + '.value_id')),
Column('bool_value', Boolean, default=False),
Column('int_value', Integer, default=0),
Column('float_value', Float, default=0),
# add some auditing columns
Column('updated_at', DateTime,
default=datetime.now),
Column('updated_by', String(50),
default=anonymous))

return keys_table, values_table, attrs_table


class VerticalAttrKey(object):

def __init__(self, name, type, description=None):
self.name = name
self.type = type
self.description = description

def __repr__(self):
return (%s(id='%s',name='%s',type='%s',description='%s')
% (self.__class__.__name__, self.id, self.name,
   self.type, self.description))

def __getitem__(self, value):
assert self.type == ENUM_TYPE
return self.enum_values[value]

def __contains__(self, value):
assert self.type == ENUM_TYPE
return value in self.enum_values

# del an enum value from this key
def __delitem__(self, value):
assert self.type == ENUM_TYPE
del self.enum_values[value]

def get(self, value, default):
return self.enum_values.get(value, None)

def get_enums(self):
assert self.type == ENUM_TYPE
return self.enum_values.keys()

def set_enum(self, value, description=None, newvalue=None):
assert self.type == ENUM_TYPE
if value in 

[sqlalchemy] Re: How to link one table to itself?

2010-08-12 Thread Alvaro Reinoso
I'm trying that, but I got different error:

Could not determine relationship direction for primaryjoin condition
'users.id = :id_1', on relationship User.mediaGroups. Specify the
'foreign_keys' argument to indicate which columns on the relationship
are foreign.

As I can see, the error is related to the users table which I don't
use in this class. However, user table is related to media_groups.
This is the user's table:

class User(rdb.Model):
Represents the user
rdb.metadata(metadata)
rdb.tablename(users)

id = Column(id, Integer, primary_key=True)
name = Column(name, String(50))
email = Column(email, String(50))

channels = relationship(Channel, secondary=user_channels,
order_by=Channel.titleView, backref=users)
mediaGroups = relationship(MediaGroup, secondary=user_media_groups,
order_by=MediaGroup.title, backref=users)

Do I need to add something else to that table?

Thanks!!!



On Aug 12, 5:15 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Aug 12, 2010, at 5:09 PM, Michael Bayer wrote:





  On Aug 12, 2010, at 4:58 PM, Alvaro Reinoso wrote:

  I'm still working on the solution. I've found out some stuff in
  internet. I guess I'm close to, but I haven't got it yet. I'm using
  this for the relation:

         mediaGroups = relationship(MediaGroup,
  secondary=media_group_groups, order_by=MediaGroup.title,
  backref='media_groups', foreign_keys =
  [media_group_groups.groupA_id, media_group_groups.groupB_id],
                                         primaryjoin = MediaGroup.id == 
  media_group_groups.groupA_id,
  secondaryjoin = MediaGroup.id == media_group_groups.groupB_id)

  I'm playing with the parameters, but I usually get this error:

  ArgumentError: Could not determine relationship direction for
  primaryjoin condition 'users.id = :id_1', on relationship
  User.mediaGroups. Specify the 'foreign_keys' argument to indicate
  which columns on the relationship are foreign.

  media_group_groups is not available when primaryjoin is evaluated as a 
  string, nor within foreign_keys which is not necessary here since your 
  meta_group_groups already has ForeignKey objects on it, so use a non-string 
  format for primaryjoin.   i will add additional examples to the declarative 
  docs.

 scratch part of that, tablenames are available in the string eval as long as 
 they're from the same MetaData:

     mediaGroup = relationship(MediaGroup,

 secondary=media_group_groups, order_by=MediaGroup.title,
 backref=media_groups, 
 primaryjoin=MediaGroup.id==media_group_groups.c.groupA_id,
 secondaryjoin=MediaGroup.id==media_group_groups.c.groupB_id

 also the error for the exampe you have above should be 'Table' object has no 
 attribute 'groupA_id'.



  Thank you!

  On Aug 12, 1:08 pm, Alvaro Reinoso alvrein...@gmail.com wrote:
  Hello,

  I'm trying to link one table to itself. I have media groups which can
  contain more media group. I created a relation many to many:

     media_group_groups = Table(
                         media_group_groups,
                         metadata,
                         Column(groupA_id, Integer, 
  ForeignKey(media_groups.id)),
                         Column(groupB_id, Integer, 
  ForeignKey(media_groups.id))
                 )

     class MediaGroup(rdb.Model):
         Represents MediaGroup class. Conteins channels and other media
  groups
         rdb.metadata(metadata)
         rdb.tablename(media_groups)

         id = Column(id, Integer, primary_key=True)
         title = Column(title, String(100))
         parents = Column(parents, String(512))

         channels = relationship(Channel, secondary=media_group_channels,
  order_by=Channel.titleView, backref=media_groups)
         mediaGroup = relationship(MediaGroup,
  secondary=media_group_groups, order_by=MediaGroup.title,
  backref=media_groups)

  I got this error:

  ArgumentError: Could not determine join condition between parent/
  child tables on relationship MediaGroup.mediaGroup. Specify a
  'primaryjoin' expression. If this is a many-to-many relationship,
  'secondaryjoin' is needed as well.

  When I create the tables I don't get any error, it's just when I add
  any element to it.
  Any idea???

  Thanks in advance!

  --
  You received this message because you are subscribed to the Google Groups 
  sqlalchemy group.
  To post to this group, send email to sqlalch...@googlegroups.com.
  To unsubscribe from this group, send email to 
  sqlalchemy+unsubscr...@googlegroups.com.
  For more options, visit this group 
  athttp://groups.google.com/group/sqlalchemy?hl=en.

  --
  You received this message because you are subscribed to the Google Groups 
  sqlalchemy group.
  To post to this group, send email to sqlalch...@googlegroups.com.
  To unsubscribe from this group, send email to 
  sqlalchemy+unsubscr...@googlegroups.com.
  For more options, visit this group 
  athttp://groups.google.com/group/sqlalchemy?hl=en.

-- 
You received 

[sqlalchemy] Specifying additional primaryjoin conditions for bidirectional adjacency list relationship

2010-08-12 Thread Nikolaj
Hi there,

I'm exploring the bidirectional adjacency list pattern described in
the documentation (the scalar relationship is intentional):

Person.child = relationship(
Person,
uselist=False,
backref=backref('parent', remote_side=Person.id)
)

However, I'd like to add an additional primaryjoin condition,
something to the effect of:

child = aliased(Person)

Person.child_bob = relationship(
child,
uselist=False,
primaryjoin=and_(
child.parent_id == Person.id,
child.name == 'Bob'
),
backref=backref('parent', remote_side=Person.id)
)

But of course I can't use an AliasedClass in the first argument to
relationship(). Similarly I can't add the relationship property onto
an aliased parent class. What's the proper way of defining such a
relationship?

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.



[sqlalchemy] Re: Multiple Sessions

2010-08-12 Thread Erich Eder
Thanks for pointing me there, Michael. Wasn't aware of that InnoDB
feature. Make all sense, now.

On Aug 13, 12:37 am, Michael Bayer mike...@zzzcomputing.com wrote:
 On Aug 12, 2010, at 7:36 AM, Erich Eder wrote:

  I've found a strange behaviour when using multiple sessions: A
  committed change to an object in one session does not get reflected in
  the other session, even after a session.expire_all() (or expire() or
  refresh() on the object. In fact, even an explicit query does not
  retrieve the changed data. I'm using MySQL. Further investigation
  showed that it happens only with InnoDB. Using MyISAM produces the
  expected results. Looks like a caching issue with InnoDB.

 its not caching, its transaction isolation, which is why expire_all() is 
 not the issue here (and why expire_all() is not really needed by itself with 
 autocommit=False - rollback() and commit() handle it).   at the end, session1 
 is still open in its second transaction which has loaded a1.data as 123.

 http://dev.mysql.com/doc/refman/5.0/en/innodb-consistent-read.html


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.