[sqlalchemy] Re: problem with backref

2006-12-23 Thread Manlio Perillo


Michael Bayer ha scritto:


the original mapping essentially expressed this relationship:

   A --  cascade=all, delete-orphan -- B

in both directions.  What that means is, there cannot be an A with no B
in the database, and there cannot be a B with no A in the database,
i.e. its either A-B or both will be deleted.  its like an oxygen
molecule, or something.

what you need to do is decide which of A and B can exist on its own
without a parent relationship.  since you want to delete rows from B
and not A, that would indicate that the mapping should be:

mapper(A, a)
mapper(
B, b,
properties={
'a': relation(
A, backref=backref('b', lazy=False, uselist=False,
   cascade='all, delete-orphan'),
uselist=False
)
}
)

i.e. the delete-orphan cascade is only in the direction from A-B.
the cascade from B-A is left at its default value of save-update, so
delete operations dont propigate from B's to A's.



Sorry, I still have problems.
Here is the code I'm using:


from sqlalchemy import *


db = create_engine('postgres://manlio:[EMAIL PROTECTED]/test', echo=True)


metadata = BoundMetaData(db)
a = Table(
'a', metadata,
Column('x', String),
Column('y', String),
PrimaryKeyConstraint('x', 'y')
)

b = Table(
'b', metadata,
Column('x', String),
Column('y', String),
Column('z', String),
PrimaryKeyConstraint('x', 'y'),
ForeignKeyConstraint(['x', 'y'], ['a.x', 'a.y'], ondelete='CASCADE')
)

metadata.create_all()


class A(object):
def __init__(self, x, y):
self.x = x
self.y = y

class B(object):
def __init__(self, x, y, z):
self.x = x
self.y = y
self.z = z


mapper(A, a)
mapper(
B, b,
properties={
'a': relation(
A, backref=backref('b', lazy=False, uselist=False,
   cascade='all, delete-orphan'),
uselist=False
)
}
)


try:
 1
conn = db.connect()
trans = conn.begin()
sess = create_session(bind_to=conn)

o = A('1', '2')
o.b = B(o.x, o.y, '3')
sess.save(o)

sess.flush()
sess.close()
trans.commit()
conn.close()


 2
conn = db.connect()
trans = conn.begin()
sess = create_session(bind_to=conn)

sess.update(o)
print o.b.z
del o.b
#sess.delete(o.b)
#o.b = None

sess.flush()
sess.close()
trans.commit()
conn.close()

 3
print o.b
s = a.select()
print conn.execute(s).fetchall()
finally:
metadata.drop_all(tables=[b])
metadata.drop_all(tables=[a])




The error is:

Traceback (most recent call last):
  File alchemy.py, line 82, in ?
print o.b
  File /usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py,
line 48, in __get__
return self.get(obj)
  File /usr/lib/python2.4/site-packages/sqlalchemy/orm/attributes.py,
line 205, in get
value = callable_()
  File /usr/lib/python2.4/site-packages/sqlalchemy/orm/strategies.py,
line 204, in lazyload
raise exceptions.InvalidRequestError(Parent instance %s is not
bound to a Session, and no contextual session is established; lazy load
operation of attribute '%s' cannot proceed % (instance.__class__,
self.key))
sqlalchemy.exceptions.InvalidRequestError: Parent instance class
'__main__.A' is not bound to a Session, and no contextual session is
established; lazy load operation of attribute 'b' cannot proceed



Thanks and regards  Manlio Perillo


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



[sqlalchemy] Additions to model not getting flushed to DB?? (Pylons)

2006-12-23 Thread Chris Shenton


I'm doing a Pylons app and must be doing something stupid because
similar logic seems to work elsewhere, but this just
isn't sticking in the DB.  I query to get existing 'contacts',
they're empty so I create a new one, append it, save and flush, but it
doesn't show up in the diagnostic queries I do.  Perhaps I'm not
seeing something obvious, any suggestions? 


   contacts = 
self.session.query(model.Contact).select_by(client_id=client.client_id)
   print #vendor.upload DBQ contacts=, contacts
   contacts = client.contacts
   print #vendor.upload DOT contacts=, contacts

   contact = model.Contact(client_id=client.client_id,
   email=row['contactemail'],
   password=row.get('contactpassword'),
   firstname=row.get('contactfirstname'),
   lastname=row.get('contactlastname'),
   )
   print #vendor.upload New contact=, contact
   print #vendor.upload Query contacts before append=, 
self.session.query(model.Contact).select()
   contacts.append(contact)
   print #vendor.upload Query contacts after  append=, 
self.session.query(model.Contact).select()
   self.session.save(contact)
   print #vendor.upload Query contacts aftersave=, 
self.session.query(model.Contact).select()
   self.session.flush()
   print #vendor.upload Query contacts after   flush=, 
self.session.query(model.Contact).select()

When I run it, you see it creates a new one but then none of the
queries find the contact from a query. An SQL query against the MySQL
DB show's it's not their either.

   #vendor.upload DBQ contacts= []
   #vendor.upload DOT contacts= []
   #vendor.upload New contact= Contact(None,9,[EMAIL PROTECTED],None,None,None 
[None, None])
   #vendor.upload Query contacts before  save= []
   #vendor.upload Query contacts after   save= []
   #vendor.upload Query contacts after  flush= []

The client and contact model and relations look like:

   client_table = Table('client', metadata,
Column('client_id',Integer,
primary_key=True),
Column('vendor_id',Integer,
ForeignKey('vendor.vendor_id'), nullable=False),
Column('name', String(40), unique=True, 
nullable=False),
Column('ts_created',   DateTime,   
default=func.current_timestamp()),
Column('ts_updated',   DateTime,   
onupdate=func.current_timestamp()),
)
   mapper(Client, client_table,
  properties={'contacts': relation(Contact, lazy=False),
  'systems':  relation(System,  lazy=False),
  })

   contact_table = Table('contact', metadata,
 Column('contact_id',Integer,
primary_key=True),
 Column('client_id',  Integer,
ForeignKey('client.client_id'), nullable=False),
 Column('email',  String(80), 
unique=True, nullable=False),
 Column('password',   String(40), 
nullable=False),
 Column('firstname',  String(40), 
nullable=True),
 Column('lastname',   String(40), 
nullable=True),
 Column('ts_created', DateTime,   
default=func.current_timestamp()),
 Column('ts_updated', DateTime,   
onupdate=func.current_timestamp()),
 )


Any ideas? Thanks!

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



[sqlalchemy] Re: table_foo.c.column_foo.autoincrement returning True always

2006-12-23 Thread Michael Bayer


the flag only applies to primary key integer columns, otherwise is
ignored.   while we might want to add that logic to the Table class, it
would be tricky because whether or not autoincrement is available has
some dialect-specific dependencies (such as, Postgres can do BIGSERIAL
on a BigInteger but cant do serial on a SmallInteger, both of which are
integers).


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



[sqlalchemy] Re: Additions to model not getting flushed to DB?? (Pylons)

2006-12-23 Thread Chris Shenton


Doh, I should have turned on the SQL echo.  Now that I have, it's even
more puzzling to me.  It shows the 'contact' being inserted and
committed -- but it never appears in MySQL!

 2006-12-23 17:33:15,140 INFO sqlalchemy.engine.base.Engine.0x..cc BEGIN
 2006-12-23 17:33:15,145 INFO sqlalchemy.engine.base.Engine.0x..cc SELECT 
current_timestamp
 2006-12-23 17:33:15,145 INFO sqlalchemy.engine.base.Engine.0x..cc []
 2006-12-23 17:33:15,150 INFO sqlalchemy.engine.base.Engine.0x..cc INSERT INTO 
contact (client_id, email, password, firstname, lastname, ts_created, 
ts_updated) VALUES (%s, %s, %s, %s, %s, %s, %s)
 2006-12-23 17:33:15,150 INFO sqlalchemy.engine.base.Engine.0x..cc [9L, '[EMAIL 
PROTECTED]', None, None, None, datetime.datetime(2006, 12, 23, 17, 33, 44), 
None]
 2006-12-23 17:33:15,158 INFO sqlalchemy.engine.base.Engine.0x..cc COMMIT

 #vendor.upload Query contacts after  flush=[]


If I switch my Pylons development.ini to use an SQLite DB, the app
works as expected until I get to the same flush():

   contact = model.Contact(client_id=client.client_id,
   email=row['contactemail'],
   password=row.get('contactpassword'),
   firstname=row.get('contactfirstname'),
   lastname=row.get('contactlastname'))
   self.session.save(contact)
   self.session.flush()

The Pylons traceback reports:

 self.session.flush()
   ...
   sqlalchemy.exceptions.SQLError: (OperationalError) SQL logic error or missing database 'INSERT INTO contact (client_id, email, password, firstname, lastname, ts_created, ts_updated) VALUES (?, ?, ?, ?, ?, ?, ?)' [1, '[EMAIL PROTECTED]', None, None, None, '2006-12-24 00:25:35', None]  


The SQL echo looks good, until the ROLLBACK:

   2006-12-23 19:25:35,874 INFO sqlalchemy.engine.base.Engine.0x..0c BEGIN
   2006-12-23 19:25:35,878 INFO sqlalchemy.engine.base.Engine.0x..0c SELECT 
current_timestamp
   2006-12-23 19:25:35,878 INFO sqlalchemy.engine.base.Engine.0x..0c []
   2006-12-23 19:25:35,879 INFO sqlalchemy.engine.base.Engine.0x..0c INSERT 
INTO contact (client_id, email, password, firstname, lastname, ts_created, 
ts_updated) VALUES (?, ?, ?, ?, ?, ?, ?)
   2006-12-23 19:25:36,031 INFO sqlalchemy.engine.base.Engine.0x..0c [1, 
'[EMAIL PROTECTED]', None, None, None, '2006-12-24 00:25:35', None]
   2006-12-23 19:25:36,086 INFO sqlalchemy.engine.base.Engine.0x..0c ROLLBACK

That self.session is created with a Pylons __before__ method:

   def __before__(self):
   self.session = session_context.current
   self.q = self.session.query(model.Vendor)

and other methods use this just fine as far as I can tell. 


How can I track down whether there's a missing database or what the
SQL logic error might be? 


Thanks.

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



[sqlalchemy] Re: problem with backref

2006-12-23 Thread Michael Bayer


dont access the unloaded b attribute on o unless it is still
attached to its session.  when you sess.close(), o is no longer
attached to a session. also, dont say del o.b, or insure that you
reassign a blank list to o.b. before accessing it again.  the del
operation deletes the list-based attribute entirely and reverts access
on it to its class-based lazy load status, which is why the lazy loader
is firing off again.


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



[sqlalchemy] Re: Additions to model not getting flushed to DB?? (Pylons)

2006-12-23 Thread Michael Bayer


seems like Pylons is not properly maintaining the session within
requests.  unless there is some way you can reproduce this problem
without any dependencies on pylons ?  is this using the newest
SA/Pylons code that Ben was recently working on ?


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



[sqlalchemy] Re: problem with backref

2006-12-23 Thread Michael Bayer


im sorry, i meant a scalar value of None, not a blank list,since you
have uselist=False.  Assign None to o.b instead of saying del o.b.


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



[sqlalchemy] Re: Additions to model not getting flushed to DB?? (Pylons)

2006-12-23 Thread Chris Shenton


Michael Bayer [EMAIL PROTECTED] writes:


seems like Pylons is not properly maintaining the session within
requests.


Yeah, it sure feels like that. :-(


unless there is some way you can reproduce this problem
without any dependencies on pylons ?  is this using the newest
SA/Pylons code that Ben was recently working on ?


Hrmmm, I'm not sure ... I am not on the bleeding edge with nightly
easy_install -U *=dev :-)

I'll see if I can reproduce in a small scale in Pylons; if so, I'll
try reproducing in standalone SA. 

Thanks for the pointers. 


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



[sqlalchemy] Re: Additions to model not getting flushed to DB?? (Pylons)

2006-12-23 Thread Philip Jenvey



On Dec 23, 2006, at 8:56 PM, Chris Shenton wrote:



Michael Bayer [EMAIL PROTECTED] writes:


seems like Pylons is not properly maintaining the session within
requests.


Yeah, it sure feels like that. :-(


unless there is some way you can reproduce this problem
without any dependencies on pylons ?  is this using the newest
SA/Pylons code that Ben was recently working on ?


Hrmmm, I'm not sure ... I am not on the bleeding edge with nightly
easy_install -U *=dev :-)


Pylons trunk (dev) provides a session_context out of the box, but the  
0.9.3 release (which it sounds like you're using) does not. Showing  
how your session_context variable is created might be helpful.


I saw a prompt in your last email:

 self.session.flush()

Are you using paster shell, or the interactive debugger? Otherwise  
nothing looks out of the ordinary minus the fact you're not seeing  
your data.


 Obvious question: are you seeing the changes made to the database  
after the commit?


--
Philip Jenvey


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