Re: [sqlalchemy] Re: negative implications of using multiple declarative Base classes

2010-08-24 Thread Chris Withers

avdd wrote:

I'm glad you brought this up.  It seems to me that the the declarative
instrumentation keys classes by their unqualified class name,
precluding using the same class name for different declarative
subclasses (ie, in different modules).


Indeed, but I suspect there's more to it than that.
My guess would be that you'd then have to use the full dotted name to 
the class, which might be problematic.


Myself, I wish we could drop the need for the registry in the 
declarative base and push all the required info down into the MetaData 
object.


What would be the problems with doing this?

Chris

--
Simplistix - Content Management, Batch Processing  Python Consulting
- http://www.simplistix.co.uk

--
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] Session uses new connection after commit

2010-08-24 Thread Julien Demoor
Hi,

I'm using PostgreSQL advisory locks in a multithreaded program. Worker
threads acquire locks with
session.execute(select([func.pg_advisory_lock(key)])) during a
transaction and release them just after  session.commit(). Sometimes
however, the connection behind the thread's session will have changed
after COMMIT, making it impossible for the thread to release the locks
it acquired. Note that I'm using scoped_session()'s class methods
everywhere.

A python script to reproduce the problem and its output are attached
below.

Is there a way to force the session to use the same connection within
a thread ? Would I then have to recycle the connections from time to
time ?

Thanks,

Julien

=== sa_pg_advisory_locks.py ==

# -*- coding: utf8 -*-
import random
import os
import threading
import time

from sqlalchemy import MetaData
from sqlalchemy.engine import create_engine
from sqlalchemy.orm import create_session, scoped_session,
sessionmaker, reconstructor
from sqlalchemy.sql import func, select

sa_engine = create_engine(os.environ['TEST_DSN'])

session = scoped_session(lambda: create_session(sa_engine,
autoflush=True, expire_on_commit=True, autocommit=False))

# Toggle this switch to see the difference in behaviour
COMMIT_BEFORE_LOCK_RELEASE = True
# COMMIT_BEFORE_LOCK_RELEASE = False

print 'Will commit %s releasing advisory lock' % ('before' if
COMMIT_BEFORE_LOCK_RELEASE else 'after')

# Synchronize program termination
event = threading.Event()

# Test function, will run concurrently in two threads
def run_test():
try:
i = 0
while 1:
if event.isSet() or i = 100:
break
# Show sign of life
if i and (i % 50 == 0):
print i
key = random.randint(1,2**16)
pid, _ = session.execute(select([func.pg_backend_pid(),
func.pg_advisory_lock(key)])).fetchone()
now = session.execute(select([func.now()])).scalar()
if COMMIT_BEFORE_LOCK_RELEASE:
session.commit()
pid_, unlocked = 
session.execute(select([func.pg_backend_pid(),
func.pg_advisory_unlock(key)])).fetchone()
if unlocked:
assert pid_ == pid
else:
raise AssertionError('Iteration %i, acquisition 
pid %i, release
pid %i\n' % (i, pid, pid_))
if not COMMIT_BEFORE_LOCK_RELEASE:
session.commit()
i += 1
except Exception:
event.set()
raise
event.set()

for i in xrange(10):
thread = threading.Thread(target=run_test)
thread.daemon = True
thread.start()

event.wait()
time.sleep(1)

== output ==

u...@host ~
$ TEST_DSN=$CPYTHON_DSN python sa_pg_advisory_locks.py
Will commit before releasing advisory lock
Exception in thread Thread-10:
Traceback (most recent call last):
  File /usr/lib/python2.6/threading.py, line 532, in
__bootstrap_inner
self.run()
  File /usr/lib/python2.6/threading.py, line 484, in run
self.__target(*self.__args, **self.__kwargs)
  File sa_pg_advisory_locks.py, line 44, in run_test
raise AssertionError('Iteration %i, acquisition pid %i, release
pid %i\n' % (i, pid, pid_))
AssertionError: Iteration 6, acquisition pid 16676, release pid 27340


Exception in thread Thread-5:
Traceback (most recent call last):
  File /usr/lib/python2.6/threading.py, line 532, in
__bootstrap_inner
self.run()
  File /usr/lib/python2.6/threading.py, line 484, in run
self.__target(*self.__args, **self.__kwargs)
  File sa_pg_advisory_locks.py, line 44, in run_test
raise AssertionError('Iteration %i, acquisition pid %i, release
pid %i\n' % (i, pid, pid_))
AssertionError: Iteration 12, acquisition pid 27340, release pid 16676


Exception in thread Thread-7:
Traceback (most recent call last):
  File /usr/lib/python2.6/threading.py, line 532, in
__bootstrap_inner
self.run()
  File /usr/lib/python2.6/threading.py, line 484, in run
self.__target(*self.__args, **self.__kwargs)
  File sa_pg_advisory_locks.py, line 44, in run_test
raise AssertionError('Iteration %i, acquisition pid %i, release
pid %i\n' % (i, pid, pid_))
AssertionError: Iteration 10, acquisition pid 18248, release pid 8452


Exception in thread Thread-3:
Traceback (most recent call last):
  File /usr/lib/python2.6/threading.py, line 532, in
__bootstrap_inner
self.run()
  File /usr/lib/python2.6/threading.py, line 484, in run
self.__target(*self.__args, **self.__kwargs)
  File sa_pg_advisory_locks.py, line 44, in run_test
raise AssertionError('Iteration %i, acquisition pid %i, release
pid %i\n' % (i, pid, pid_))
AssertionError: Iteration 18, acquisition pid 8452, release pid 18248



u...@host ~
$ 

[sqlalchemy] where would you store meta data .. ?

2010-08-24 Thread Julien Cigar

Hello,

I'm building a CMS-like webapp where I use inheritance a lot.

One feature that I would like to allow is that when an user add a new 
section (a new container), he would be able to select the default 
with_polymorphic() clause, order_by, objects per page when browsing the 
container, etc.


I wondered where is the best place to store those meta data (in the 
database itself ? in a separate table ? .. ?), and in which format (JSON 
? serialized object ? ... ?) ?


I would like to avoid a seqscan of a lot of rows and any breakage when, 
for example, a mapped child class (polymorphic_identity) is removed, but 
was selected for a polymorphic loading in one or more containers.


I don't know if this is the best place to ask but ... let's try :-)

Thanks,
Julien

--
No trees were killed in the creation of this message.
However, many electrons were terribly inconvenienced.

--
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.

attachment: jcigar.vcf

[sqlalchemy] begginers query question

2010-08-24 Thread Dobrysmak
Hi guys.

I've got a little problem with the sqlalchemy syntax.
I've got two tables with relations:

Table_Goups
id int(4) PrimaryKey not null,
name varchar(50) not null;

and

Table_User
id int(4) Primary Key not null,
login varchar(50) not null,
id_group int(4) Foreign Key not null;

i would like to build a query that would gets the user data from
Table_User and the id_group but insted od showing the id_group number
i want to show the Table_Groups.name

Can anyone help?

-- 
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: negative implications of using multiple declarative Base classes

2010-08-24 Thread Michael Bayer

On Aug 24, 2010, at 3:04 AM, Chris Withers wrote:

 avdd wrote:
 I'm glad you brought this up.  It seems to me that the the declarative
 instrumentation keys classes by their unqualified class name,
 precluding using the same class name for different declarative
 subclasses (ie, in different modules).
 
 Indeed, but I suspect there's more to it than that.
 My guess would be that you'd then have to use the full dotted name to the 
 class, which might be problematic.
 
 Myself, I wish we could drop the need for the registry in the declarative 
 base and push all the required info down into the MetaData object.
 
 What would be the problems with doing this?

breaks encapsulation.



 
 Chris
 
 -- 
 Simplistix - Content Management, Batch Processing  Python Consulting
- http://www.simplistix.co.uk
 
 -- 
 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] Session uses new connection after commit

2010-08-24 Thread Michael Bayer

On Aug 24, 2010, at 6:12 AM, Julien Demoor wrote:

 Hi,
 
 I'm using PostgreSQL advisory locks in a multithreaded program. Worker
 threads acquire locks with
 session.execute(select([func.pg_advisory_lock(key)])) during a
 transaction and release them just after  session.commit(). Sometimes
 however, the connection behind the thread's session will have changed
 after COMMIT, making it impossible for the thread to release the locks
 it acquired. Note that I'm using scoped_session()'s class methods
 everywhere.
 
 A python script to reproduce the problem and its output are attached
 below.
 
 Is there a way to force the session to use the same connection within
 a thread ? Would I then have to recycle the connections from time to
 time ?

I think the most direct way is to bind the Session to a specific connection:

conn = engine.connect()
sess = Session(bind=conn)


then when the scope of work with the connection is complete:

sess.close()
conn.close()

the indirect way would be to play games with the connection pool, but in this 
case your application should already have explicit boundaries where you'd like 
this connection to stay in play so the above approach is straightforward.



 
 Thanks,
 
 Julien
 
 === sa_pg_advisory_locks.py ==
 
 # -*- coding: utf8 -*-
 import random
 import os
 import threading
 import time
 
 from sqlalchemy import MetaData
 from sqlalchemy.engine import create_engine
 from sqlalchemy.orm import create_session, scoped_session,
 sessionmaker, reconstructor
 from sqlalchemy.sql import func, select
 
 sa_engine = create_engine(os.environ['TEST_DSN'])
 
 session = scoped_session(lambda: create_session(sa_engine,
 autoflush=True, expire_on_commit=True, autocommit=False))
 
 # Toggle this switch to see the difference in behaviour
 COMMIT_BEFORE_LOCK_RELEASE = True
 # COMMIT_BEFORE_LOCK_RELEASE = False
 
 print 'Will commit %s releasing advisory lock' % ('before' if
 COMMIT_BEFORE_LOCK_RELEASE else 'after')
 
 # Synchronize program termination
 event = threading.Event()
 
 # Test function, will run concurrently in two threads
 def run_test():
   try:
   i = 0
   while 1:
   if event.isSet() or i = 100:
   break
   # Show sign of life
   if i and (i % 50 == 0):
   print i
   key = random.randint(1,2**16)
   pid, _ = session.execute(select([func.pg_backend_pid(),
 func.pg_advisory_lock(key)])).fetchone()
   now = session.execute(select([func.now()])).scalar()
   if COMMIT_BEFORE_LOCK_RELEASE:
   session.commit()
   pid_, unlocked = 
 session.execute(select([func.pg_backend_pid(),
 func.pg_advisory_unlock(key)])).fetchone()
   if unlocked:
   assert pid_ == pid
   else:
   raise AssertionError('Iteration %i, acquisition 
 pid %i, release
 pid %i\n' % (i, pid, pid_))
   if not COMMIT_BEFORE_LOCK_RELEASE:
   session.commit()
   i += 1
   except Exception:
   event.set()
   raise
   event.set()
 
 for i in xrange(10):
   thread = threading.Thread(target=run_test)
   thread.daemon = True
   thread.start()
 
 event.wait()
 time.sleep(1)
 
 == output ==
 
 u...@host ~
 $ TEST_DSN=$CPYTHON_DSN python sa_pg_advisory_locks.py
 Will commit before releasing advisory lock
 Exception in thread Thread-10:
 Traceback (most recent call last):
  File /usr/lib/python2.6/threading.py, line 532, in
 __bootstrap_inner
self.run()
  File /usr/lib/python2.6/threading.py, line 484, in run
self.__target(*self.__args, **self.__kwargs)
  File sa_pg_advisory_locks.py, line 44, in run_test
raise AssertionError('Iteration %i, acquisition pid %i, release
 pid %i\n' % (i, pid, pid_))
 AssertionError: Iteration 6, acquisition pid 16676, release pid 27340
 
 
 Exception in thread Thread-5:
 Traceback (most recent call last):
  File /usr/lib/python2.6/threading.py, line 532, in
 __bootstrap_inner
self.run()
  File /usr/lib/python2.6/threading.py, line 484, in run
self.__target(*self.__args, **self.__kwargs)
  File sa_pg_advisory_locks.py, line 44, in run_test
raise AssertionError('Iteration %i, acquisition pid %i, release
 pid %i\n' % (i, pid, pid_))
 AssertionError: Iteration 12, acquisition pid 27340, release pid 16676
 
 
 Exception in thread Thread-7:
 Traceback (most recent call last):
  File /usr/lib/python2.6/threading.py, line 532, in
 __bootstrap_inner
self.run()
  File /usr/lib/python2.6/threading.py, line 484, in run
self.__target(*self.__args, **self.__kwargs)
  File sa_pg_advisory_locks.py, line 44, in run_test
raise AssertionError('Iteration %i, acquisition pid %i, release
 pid %i\n' % (i, pid, pid_))

Re: [sqlalchemy] begginers query question

2010-08-24 Thread werner

 Hi,

On 24/08/2010 10:14, Dobrysmak wrote:

Hi guys.

I've got a little problem with the sqlalchemy syntax.
I've got two tables with relations:

Table_Goups
id int(4) PrimaryKey not null,
name varchar(50) not null;

and

Table_User
id int(4) Primary Key not null,
login varchar(50) not null,
id_group int(4) Foreign Key not null;

i would like to build a query that would gets the user data from
Table_User and the id_group but insted od showing the id_group number
i want to show the Table_Groups.name

Can anyone help?


I use SA declarative, so you would define something like this in your model:

class Group(Base):
__table__ = sa.Table(u'groups', metadata,
sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), 
primary_key=True, nullable=False),
sa.Column(u'name', sa.String(length=70, convert_unicode=False), 
nullable=False),

)


class User(Base):
__table__ = sa.Table(u'users', metadata,
sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), 
primary_key=True, nullable=False),
sa.Column(u'name', sa.String(length=70, convert_unicode=False), 
nullable=False),
sa.Column(u'fk_group', sa.Integer(), sa.ForeignKey(u'groups.id'), 
nullable=False),

)

group = sao.relation('Group', backref='user')

And then to query you could do e.g. this:

for usr in session.query(db.User).all():
print 'user: %s, group name: %s' % (usr.name, usr.group.name)

Check out the SA doc, especially the tutorials:
http://www.sqlalchemy.org/docs/ormtutorial.html
http://www.sqlalchemy.org/docs/ormtutorial.html#creating-table-class-and-mapper-all-at-once-declaratively

Hope this helps
Werner


--
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] begginers query question

2010-08-24 Thread werner

 On 24/08/2010 15:53, werner wrote:

 Hi,

On 24/08/2010 10:14, Dobrysmak wrote:

Hi guys.

I've got a little problem with the sqlalchemy syntax.
I've got two tables with relations:

Table_Goups
id int(4) PrimaryKey not null,
name varchar(50) not null;

and

Table_User
id int(4) Primary Key not null,
login varchar(50) not null,
id_group int(4) Foreign Key not null;

i would like to build a query that would gets the user data from
Table_User and the id_group but insted od showing the id_group number
i want to show the Table_Groups.name

Can anyone help?

I use SA declarative, so you would define something like this in your 
model:


class Group(Base):
__table__ = sa.Table(u'groups', metadata,
sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), 
primary_key=True, nullable=False),
sa.Column(u'name', sa.String(length=70, convert_unicode=False), 
nullable=False),

)


Oops, a copy/paste error, should be: sa.Sequence('gen_group_id')


class User(Base):
__table__ = sa.Table(u'users', metadata,
sa.Column(u'id', sa.Integer(), sa.Sequence('gen_contact_id'), 
primary_key=True, nullable=False), 

and another one, a copy/paste error, should be: sa.Sequence('gen_user_id')
sa.Column(u'name', sa.String(length=70, convert_unicode=False), 
nullable=False),
sa.Column(u'fk_group', sa.Integer(), sa.ForeignKey(u'groups.id'), 
nullable=False),

)

group = sao.relation('Group', backref='user')

And then to query you could do e.g. this:

for usr in session.query(db.User).all():
print 'user: %s, group name: %s' % (usr.name, usr.group.name)

Check out the SA doc, especially the tutorials:
http://www.sqlalchemy.org/docs/ormtutorial.html
http://www.sqlalchemy.org/docs/ormtutorial.html#creating-table-class-and-mapper-all-at-once-declaratively 



Hope this helps
Werner





--
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: Session uses new connection after commit

2010-08-24 Thread Julien Demoor
Thanks a lot, that solves my problem. Also it seems to work well
without instantiating the scoped session, so this is perfect.

On Aug 24, 3:13 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Aug 24, 2010, at 6:12 AM, Julien Demoor wrote:



  Hi,

  I'm using PostgreSQL advisory locks in a multithreaded program. Worker
  threads acquire locks with
  session.execute(select([func.pg_advisory_lock(key)])) during a
  transaction and release them just after  session.commit(). Sometimes
  however, the connection behind the thread's session will have changed
  after COMMIT, making it impossible for the thread to release the locks
  it acquired. Note that I'm using scoped_session()'s class methods
  everywhere.

  A python script to reproduce the problem and its output are attached
  below.

  Is there a way to force the session to use the same connection within
  a thread ? Would I then have to recycle the connections from time to
  time ?

 I think the most direct way is to bind the Session to a specific connection:

 conn = engine.connect()
 sess = Session(bind=conn)

 then when the scope of work with the connection is complete:

 sess.close()
 conn.close()

 the indirect way would be to play games with the connection pool, but in 
 this case your application should already have explicit boundaries where 
 you'd like this connection to stay in play so the above approach is 
 straightforward.



  Thanks,

  Julien

  === sa_pg_advisory_locks.py ==

  # -*- coding: utf8 -*-
  import random
  import os
  import threading
  import time

  from sqlalchemy import MetaData
  from sqlalchemy.engine import create_engine
  from sqlalchemy.orm import create_session, scoped_session,
  sessionmaker, reconstructor
  from sqlalchemy.sql import func, select

  sa_engine = create_engine(os.environ['TEST_DSN'])

  session = scoped_session(lambda: create_session(sa_engine,
  autoflush=True, expire_on_commit=True, autocommit=False))

  # Toggle this switch to see the difference in behaviour
  COMMIT_BEFORE_LOCK_RELEASE = True
  # COMMIT_BEFORE_LOCK_RELEASE = False

  print 'Will commit %s releasing advisory lock' % ('before' if
  COMMIT_BEFORE_LOCK_RELEASE else 'after')

  # Synchronize program termination
  event = threading.Event()

  # Test function, will run concurrently in two threads
  def run_test():
     try:
             i = 0
             while 1:
                     if event.isSet() or i = 100:
                             break
                     # Show sign of life
                     if i and (i % 50 == 0):
                             print i
                     key = random.randint(1,2**16)
                     pid, _ = session.execute(select([func.pg_backend_pid(),
  func.pg_advisory_lock(key)])).fetchone()
                     now = session.execute(select([func.now()])).scalar()
                     if COMMIT_BEFORE_LOCK_RELEASE:
                             session.commit()
                     pid_, unlocked = 
  session.execute(select([func.pg_backend_pid(),
  func.pg_advisory_unlock(key)])).fetchone()
                     if unlocked:
                             assert pid_ == pid
                     else:
                             raise AssertionError('Iteration %i, acquisition 
  pid %i, release
  pid %i\n' % (i, pid, pid_))
                     if not COMMIT_BEFORE_LOCK_RELEASE:
                             session.commit()
                     i += 1
     except Exception:
             event.set()
             raise
     event.set()

  for i in xrange(10):
     thread = threading.Thread(target=run_test)
     thread.daemon = True
     thread.start()

  event.wait()
  time.sleep(1)

  == output ==

  u...@host ~
  $ TEST_DSN=$CPYTHON_DSN python sa_pg_advisory_locks.py
  Will commit before releasing advisory lock
  Exception in thread Thread-10:
  Traceback (most recent call last):
   File /usr/lib/python2.6/threading.py, line 532, in
  __bootstrap_inner
     self.run()
   File /usr/lib/python2.6/threading.py, line 484, in run
     self.__target(*self.__args, **self.__kwargs)
   File sa_pg_advisory_locks.py, line 44, in run_test
     raise AssertionError('Iteration %i, acquisition pid %i, release
  pid %i\n' % (i, pid, pid_))
  AssertionError: Iteration 6, acquisition pid 16676, release pid 27340

  Exception in thread Thread-5:
  Traceback (most recent call last):
   File /usr/lib/python2.6/threading.py, line 532, in
  __bootstrap_inner
     self.run()
   File /usr/lib/python2.6/threading.py, line 484, in run
     self.__target(*self.__args, **self.__kwargs)
   File sa_pg_advisory_locks.py, line 44, in run_test
     raise AssertionError('Iteration %i, acquisition pid %i, release
  pid %i\n' % (i, pid, pid_))
  AssertionError: Iteration 12, acquisition pid 27340, release pid 16676

  Exception in thread Thread-7:
  Traceback (most recent call last):
   File /usr/lib/python2.6/threading.py, line 532, in
  __bootstrap_inner
     self.run()
   File /usr/lib/python2.6/threading.py, line 484, 

[sqlalchemy] TypeDecorator Problem with basic association pattern

2010-08-24 Thread Frank
Hello,

I am trying to reflect the example from
http://hg.sqlalchemy.org/sqlalchemy/file/04c17c7d88d6/examples/association/basic_association.py
but with my own data structures.

I want to manage nutrients, nutrient values and nutrition lists.
Therefore I have created a custom data type weight which helps me
doing calculations with weights in different units. The relation
between nutrients and nutrition lists is m:n, one list can have many
nutrients and nutrients can be in many lists. The association table
(nutrition values) stores the amount of a nutrient associated to one
list. I think I got things working mostly, but flushing my data to the
database breaks the program:
http://paste.pocoo.org/show/253961/

From what I understand from the message, there seems to be a problem
with my custom data type. Maybe someone with more skill in sqlalchemy
than me can shed some light on the matter ...

Here's the full script

http://paste.pocoo.org/show/253956/

Many thanks

Frank

-- 
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] TypeDecorator Problem with basic association pattern

2010-08-24 Thread Michael Bayer

On Aug 24, 2010, at 11:03 AM, Frank wrote:

 Hello,
 
 I am trying to reflect the example from
 http://hg.sqlalchemy.org/sqlalchemy/file/04c17c7d88d6/examples/association/basic_association.py
 but with my own data structures.
 
 I want to manage nutrients, nutrient values and nutrition lists.
 Therefore I have created a custom data type weight which helps me
 doing calculations with weights in different units. The relation
 between nutrients and nutrition lists is m:n, one list can have many
 nutrients and nutrients can be in many lists. The association table
 (nutrition values) stores the amount of a nutrient associated to one
 list. I think I got things working mostly, but flushing my data to the
 database breaks the program:
 http://paste.pocoo.org/show/253961/
 
 From what I understand from the message, there seems to be a problem
 with my custom data type. Maybe someone with more skill in sqlalchemy
 than me can shed some light on the matter ...
 
 Here's the full script
 
 http://paste.pocoo.org/show/253956/

the TypeDecorator just needs to handle the case where the bind or result value 
is None:

class WeightType(types.TypeDecorator):

impl = types.Numeric

def process_bind_param(self, weight, dialect):
if weight is None:
return None
return weight.base_value

def process_result_value(self, value, dialect):
if value is None:
return None
return Weight(value, g)


script runs fine after that.  You probably meant to name the nutrient_weight 
column as weight, or otherwise remap the attribute on the NutritionValue 
class mapper with that name.



 
 Many thanks
 
 Frank
 
 -- 
 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] upgrading code with prop.backref from 0.5 - 0.6

2010-08-24 Thread Alessandro Dentella
On Sat, Aug 21, 2010 at 01:45:48PM -0400, Michael Bayer wrote:
  columns in a property
   column = prop.columns[0]
  
   props = []
   for pr in mapper.iterate_properties:
if isinstance(pr, properties.RelationProperty):
if pr.direction.name in ('MANYTOONE',):
for col in pr.local_remote_pairs[0]:
# I can't use col in p.local_remote_pairs
# as it uses 'col == p.local_remote_pairs' that evaluates
# to a BinaryExpression
if column is col:
try:
if pr.backref.prop.cascade.delete_orphan:
props += [pr]
except AttributeError, e:
pass
   return tuple(props)
  
  This fails in sqla 0.6 as pr.backref is empty. Which is the correct
  way to
  get the properties that have a backref that have cascade with
  delete_orphan?
 
 
 why not put some info on the director_id column (i.e. Column(, 
 info={'foo':'bar'}) ) that gives your application the information what you 
 need in a succinct and direct way.   There's no public API that links 
 relationships to backrefs and the poking through lists of columns is hacky 
 too.   I could tell you where they're linked but it can change at any time.


I wasn't aware of 'info' option. I do appreciate how easy it is to implement
it this way. On the other hand the other approch didn't even need special
configuration. 

Info option is clearly very handy. At the moment I implemented an image
field in sqlkit, (that's just a bunch of handler in the gui). In order to do
that I used a type inherited with no addition, just to understand that that
field is the path to an Image:

  class Image(String): pass

clearly another alternative would be to use info={ 'image': true} or
similar. Is there some caveat that would make one preferred over the other?

TIA

sandro
*:-)


-- 
Sandro Dentella  *:-)
http://sqlkit.argolinux.orgSQLkit home page - PyGTK/python/sqlalchemy

-- 
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] orm object, before after

2010-08-24 Thread Michael Hipp
I'm holding an orm object that will have changes made to it. Once done it will 
be passed to the business logic layer that will have to make decisions from the 
before and after state of the object...


What's the best way to get an object, save its state ('before'), modify it 
('after) without any chance of the modifications creeping into the before? 
Assume both copies are from the same session.


Thanks,
Michael

--
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] orm object, before after

2010-08-24 Thread Michael Bayer

On Aug 24, 2010, at 2:08 PM, Michael Hipp wrote:

 I'm holding an orm object that will have changes made to it. Once done it 
 will be passed to the business logic layer that will have to make decisions 
 from the before and after state of the object...
 
 What's the best way to get an object, save its state ('before'), modify it 
 ('after) without any chance of the modifications creeping into the before? 
 Assume both copies are from the same session.

You'd probably call session.flush() (or commit(), depending on how you are 
scoping your transaction around this operation) before you do anything to it.   
Then, if you'd like the subsequent modifications to not go to the database at 
all until some later point, you'd proceed with your subsequent operations with 
autoflush turned off - recipes for that are at 
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush .



 
 Thanks,
 Michael
 
 -- 
 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 DeclarativeBase

2010-08-24 Thread waugust
Greetings,

I was playing around and trying to extend the DeclarativeBase with
some Elixir like functions...

I may be to green in Python itself that I'm missing something though,
here's what I got...

 class ModelBase(DeclarativeMeta):

@classmethod
def get(cls, id):
row = meta.Session.query(cls).filter_by(id=id).one()
return row

DeclarativeBase = declarative_base(metaclass=ModelBase)
metadata = DeclarativeBase.metadata

uhhh... so how does the introspection work here (if any)? I'm I a bit
too naive here? calling cls.__class__, cls.__table__, or
cls.__call__() doesn't seem to do it...

-- 
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] orm object, before after

2010-08-24 Thread Michael Hipp

On 8/24/2010 1:51 PM, Michael Bayer wrote:


On Aug 24, 2010, at 2:08 PM, Michael Hipp wrote:


I'm holding an orm object that will have changes made to it. Once done it will 
be passed to the business logic layer that will have to make decisions from the 
before and after state of the object...

What's the best way to get an object, save its state ('before'), modify it 
('after) without any chance of the modifications creeping into the before? 
Assume both copies are from the same session.


You'd probably call session.flush() (or commit(), depending on how you are 
scoping your transaction around this operation) before you do anything to it.   
Then, if you'd like the subsequent modifications to not go to the database at 
all until some later point, you'd proceed with your subsequent operations with 
autoflush turned off - recipes for that are at 
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush .


Thank you. But I didn't understand any of that ... at least as it 
relates to my question.


How do I make a copy of an orm object such that modifications to the 
copy do not affect the original?


(Obviously I could detach one of them, but then it becomes useless as 
none of the attributes can be accessed.)


Could you perhaps repeat the answer in baby-talk language?

Thanks,
Michael

--
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] orm object, before after

2010-08-24 Thread Michael Bayer
Michael Hipp wrote:
 On 8/24/2010 1:51 PM, Michael Bayer wrote:

 On Aug 24, 2010, at 2:08 PM, Michael Hipp wrote:

 I'm holding an orm object that will have changes made to it. Once done
 it will be passed to the business logic layer that will have to make
 decisions from the before and after state of the object...

 What's the best way to get an object, save its state ('before'), modify
 it ('after) without any chance of the modifications creeping into the
 before? Assume both copies are from the same session.

 You'd probably call session.flush() (or commit(), depending on how you
 are scoping your transaction around this operation) before you do
 anything to it.   Then, if you'd like the subsequent modifications to
 not go to the database at all until some later point, you'd proceed with
 your subsequent operations with autoflush turned off - recipes for that
 are at http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DisableAutoflush
 .

 Thank you. But I didn't understand any of that ... at least as it
 relates to my question.

 How do I make a copy of an orm object such that modifications to the
 copy do not affect the original?

I'm sorry for misunderstanding, but if you read your original question
you'll note that you used the word copies exactly once and not in any
way that made much sense - the main noun was an orm object, singular,
and the next paragraph referred again to an object and it.

The mapped object has a member _sa_instance_state that you basically
don't want to transfer to your new object.You want it to have its own
_sa_instance_state and this comes from calling the plain constructor,
which the copy module, if that's what you're using, does not use.   You
also want to set attributes normally, not populating __dict__ directly.  
So just basically don't use the copy module.

Just construct a new object.

x = MyObject(foo=myoldobject.foo, bar=myoldobject.bar).

or

x = MyObject()
for a in dir(myoldobject):
if not a.startswith('_'):
setattr(x, a, getattr(myoldobject, a))

 Could you perhaps repeat the answer in baby-talk language?

Babies don't know how to program computers in the first place, so I'd aim
higher than that.


-- 
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] Extending DeclarativeBase

2010-08-24 Thread Michael Bayer

On Aug 24, 2010, at 7:54 PM, waugust wrote:

 Greetings,
 
 I was playing around and trying to extend the DeclarativeBase with
 some Elixir like functions...
 
 I may be to green in Python itself that I'm missing something though,
 here's what I got...
 
 class ModelBase(DeclarativeMeta):
 
@classmethod
def get(cls, id):
row = meta.Session.query(cls).filter_by(id=id).one()
return row
 
 DeclarativeBase = declarative_base(metaclass=ModelBase)
 metadata = DeclarativeBase.metadata

A metaclass is a subclass of type, and represents special behavior added to 
your classes' type, not the class itself.   If that doesn't make much sense, 
this is common as metaclasses are a little hard to grasp at first, theres a 
decent intro at http://www.voidspace.org.uk/python/articles/metaclasses.shtml.

anyway if you're just looking for classmethods that are common to all your 
mapped classes, use either a mixin (plenty of mixin info in the declarative 
docs) or specify a base class to declarative_meta using cls - the resulting 
class will be a subclass of the class you send.  It defaults to object.



 
 uhhh... so how does the introspection work here (if any)? I'm I a bit
 too naive here? calling cls.__class__, cls.__table__, or
 cls.__call__() doesn't seem to do it...
 
 -- 
 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] How to delete in ORM without querying first?

2010-08-24 Thread Russell Warren
In the code below I set up two users using an orm session, and then
delete one of them with a second orm session.


import sqlalchemy as sa
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker

Base = declarative_base()
class User(Base):
__tablename__ = users
id = sa.Column(sa.Integer, primary_key=True)
name = sa.Column(sa.String)
fullname = sa.Column(sa.String)

def __init__(self, name, fullname):
self.name = name
self.fullname = fullname

import os
dbEngine = sa.create_engine(sqlite://, echo = True)
Base.metadata.create_all(dbEngine)

Session = sessionmaker(bind = dbEngine,
   autoflush = True,
   autocommit = False)

#Add some data...
s1 = Session()
u1 = User(fred, Fred Flintstone)
u2 = User(barney, Barney Rubble)
s1.add(u1)
s1.add(u2)
s1.commit()

#delete the fred user...
name_to_delete = fred
s2 = Session()
fred = s2.query(User).filter_by(name = name_to_delete).first()
s2.delete(fred)
s2.commit()


In this reduced example I magically know the user name I want to
delete (fred) and know that it exists.  I also obviously don't need
the second session in this example, but it is a reduction of my
problem.

The SQL query result for the second session is below:

BEGIN
SELECT users.id AS users_id, users.name AS users_name, users.fullname
AS users_fullname
FROM users
WHERE users.name = ?
LIMIT 1 OFFSET 0
('fred',)

DELETE FROM users WHERE users.id = ?
(1,)
COMMIT

The first query is wasteful for what I'm trying to achieve, which is
to delete the user whose user.name I *know* is there (even if I didn't
know, I'd be content to catch the exception).

What I can't figure out is... with the second session, what is the
correct/best way to do a simple deletion without requiring a mapped
orm object to give to session.delete?  Do I need to leave the orm
world to do this?  I would rather not resort to session.execute if at
all possible.

-- 
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 delete in ORM without querying first?

2010-08-24 Thread Russell Warren
On Aug 25, 12:01 am, Fernando Takai fernando.ta...@gmail.com wrote:
 Have you tried:

  #delete the fred user...
  name_to_delete = fred
  s2 = Session()
  s2.query(User).filter_by(name = name_to_delete).delete()
  s2.commit()

 ?

No I had not... :(  That works absolutely perfectly, though with just
enough SQL.  Thanks!

I clearly need to get my head wrapped more around how sqla querying
works.  That is not yet intuitive to me how that works inside.  I
likely have examples like that (doing a full SELECT prior to what I
actually want to do) peppered throughout my code.

-- 
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.