[sqlalchemy] post_update fails with backrefs set

2010-05-19 Thread Brad Wells
In upgrading to 0.6.0 I've found a regression in behavior for
relationships with backrefs that require post_update=True.

from sqlalchemy import Table, Column, Integer, String, MetaData,
create_engine, ForeignKey, ForeignKeyConstraint
from sqlalchemy.orm import relation, sessionmaker, scoped_session,
synonym, object_session, mapper, backref

engine = create_engine('sqlite:///', echo=False)

Session = scoped_session(sessionmaker(autoflush=True,
autocommit=False, bind=engine))
metadata = MetaData()

contacts = Table('contacts', metadata,
  Column('id', Integer, primary_key=True),
  Column('name', String(35)),
  Column('account_id', Integer),
  ForeignKeyConstraint(['account_id'], ['accounts.id']))

accounts = Table('accounts', metadata,
 Column('id', Integer, primary_key=True),
 Column('name', String(35)),
 Column('created_by_id', Integer),
 ForeignKeyConstraint(['created_by_id'],
['contacts.id'], name='fk1', use_alter=True))

class Contact(object): pass
class Account(object): pass

mapper(Contact, contacts, properties={
'account': relation(Account,
 
primaryjoin=contacts.c.account_id==accounts.c.id,
post_update=True,
#backref=backref('contacts', post_update=True)
backref='contacts'
)
})
mapper(Account, accounts, properties={
'created_by': relation(Contact,
primaryjoin=accounts.c.created_by_id==contacts.c.id),
#'contacts': relation(Contact,
primaryjoin=accounts.c.id==contacts.c.account_id)
})

metadata.create_all(bind=engine)

# create basic data
frank = Contact()
frank.name = Frank
Session.add(frank)

finc = Account()
finc.name = Frank Inc.
frank.account = finc
Session.add(finc)

Session.commit()
Session.expunge_all()

# reproduce the problem
bob = Contact()
bob.name = 'Bob'
Session.add(bob)

frank = Session.query(Contact).filter_by(name='Frank').first()
finc = frank.account

bob.account = finc

assert bob.account == finc
Session.commit()
assert bob.account == finc

If either backref on the 'account' relation of Contact is set then the
UPDATE fails to issue. If the 'contacts' relation is defined directly
on Account or the backref isn't defined at all then everything works
as expected. This is tested on SQLAlchemy 0.6.0 with Python 2.6. I
verified this as working under 0.5.8.

-- 
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: reflecting (autoload=True) MySQL tinyint(1) fields

2010-05-04 Thread Brad Wells
The docs for the MySQL dialect need to be updated to reflect this
change. See 
http://www.sqlalchemy.org/docs/reference/dialects/mysql.html#sqlalchemy.dialects.mysql.TINYINT

For what it's worth I'd really like to see this remain as an optional
behavior. The BOOL/BOOLEN column types in MySQL are synonyms for
TINYINT(1). Someone creating columns using BOOLs might reasonably
expect to reflect that intention when autoloading. Really though, I
just want a way to avoid manually overriding 200 column definitions.
Is there a reasonable way to do that as is?


On Mar 27, 5:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Mar 27, 2010, at 5:17 PM, Michael Bayer wrote:





  On Mar 27, 2010, at 4:16 PM, Lloyd Kvam wrote:

  I've just discovered that some tinyint (8-bit) fields have had their
  values limited to 0 and 1 regardless of actual value supplied.  Digging
  through the documentation, I've learned that when MySQL tables are
  reflected, tinyint(1) fields are processed as booleans.

  I did not find emails from others howling in pain, so I suppose most
  people are either happy with this behavior or unaffected.  I understand
  why a bool column definition would be mapped to tinyint(1).  However,
  doing the reverse, mapping tinyint(1) to bool, discards bits that MySQL
  would not discard.

  For me this was a misfeature.  I would think that supplying bools to an
  integer field would work OK.  In python 2 + True == 3.  So people using
  booleans should not have too much difficulty, would they?  Is there any
  chance you'd consider autoloading tinyint(1) as an integer field?

  sure i will remove this behavior today.

 it is out in r95ac46ca88ee.



  --
  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 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: reflecting (autoload=True) MySQL tinyint(1) fields

2010-05-04 Thread Brad Wells
0/1 generally works in Python but won't convert to formats with native
boolean values correctly, in my case JSON.

Just a note, your suggestion works for me but will fail for any
unsigned columns.

I have a working solution so I'm fine with moving on from the issue,
Overall however, with MySQL's lack of a true boolean data type this
change leaves MySQL users with no particularly clean way to represent
true boolean types. Just my two cents.

Thanks for the help.

On May 4, 2:06 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On May 4, 2010, at 1:22 PM, Brad Wells wrote:

  The docs for the MySQL dialect need to be updated to reflect this
  change. 
  Seehttp://www.sqlalchemy.org/docs/reference/dialects/mysql.html#sqlalche...

  For what it's worth I'd really like to see this remain as an optional
  behavior. The BOOL/BOOLEN column types in MySQL are synonyms for
  TINYINT(1). Someone creating columns using BOOLs might reasonably
  expect to reflect that intention when autoloading. Really though, I
  just want a way to avoid manually overriding 200 column definitions.
  Is there a reasonable way to do that as is?

 if you reflect as TINYINT you still get a 0/1 back in results and it still 
 accepts True/False.    You really need it to give you the True/ False 
 tokens ?

 this is not entirely de facto in its methodology but this should work for 
 now:

 # before create_engine is called

 from sqlalchemy.dialects.mysql import base
 base.ischema_names['tinyint'] = base.BOOLEAN





  On Mar 27, 5:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  On Mar 27, 2010, at 5:17 PM, Michael Bayer wrote:

  On Mar 27, 2010, at 4:16 PM, Lloyd Kvam wrote:

  I've just discovered that some tinyint (8-bit) fields have had their
  values limited to 0 and 1 regardless of actual value supplied.  Digging
  through the documentation, I've learned that when MySQL tables are
  reflected, tinyint(1) fields are processed as booleans.

  I did not find emails from others howling in pain, so I suppose most
  people are either happy with this behavior or unaffected.  I understand
  why a bool column definition would be mapped to tinyint(1).  However,
  doing the reverse, mapping tinyint(1) to bool, discards bits that MySQL
  would not discard.

  For me this was a misfeature.  I would think that supplying bools to an
  integer field would work OK.  In python 2 + True == 3.  So people using
  booleans should not have too much difficulty, would they?  Is there any
  chance you'd consider autoloading tinyint(1) as an integer field?

  sure i will remove this behavior today.

  it is out in r95ac46ca88ee.

  --
  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 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 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-Aware Mapper deprecation page

2009-07-27 Thread Brad Wells

Single table inheritance is broken in the given mapper creating
function on the deprecation guide page. Returning the mapper corrects
the issue.

def session_mapper(scoped_session):
def mapper(cls, *args, **kwargs):
cls.query = scoped_session.query_property()
return sqla_mapper(cls, *args, **kwargs)
return mapper

Thank you for the concise guide.
--~--~-~--~~~---~--~~
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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Column expressions and .count()

2009-07-13 Thread Brad Wells

Is it possible to perform a query.count() on a query with a labeled
column expression without count() adding the subselect? I need to
filter on the value of the expression and get a count for a paged view.
--~--~-~--~~~---~--~~
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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] Re: 0.4 to 0.5 upgrade and 'One-to-many relation fails with unsaved, pending instance and is an orphan' error

2009-07-08 Thread Brad Wells

Thank you for the detailed explanation of the problem and my possible
solutions.

On Jul 3, 10:14 am, Michael Bayer mike...@zzzcomputing.com wrote:
 oh man, i missed the biggest part of this one, after I noticed that  
 you weren't doing anything to put the PhoneNumber in the session.    
 Don't use Session.mapper.  That is the main problem you're having in  
 this specific case.   Auto-adding free-standing objects to the session  
 is a bad idea and I've downplayed the crap out of this legacy feature  
 for years now.

 On Jul 2, 2009, at 7:21 PM, Brad Wells wrote:



  In the process of upgrading from 0.4 to 0.5 I've come across a
  troubling issue. With the following setup:

  

  from sqlalchemy import Table, Column, Integer, String, MetaData,
  create_engine, ForeignKey
  from sqlalchemy.orm import relation, sessionmaker, scoped_session

  engine = create_engine('sqlite:///mystuff.sqlite', echo=True)

  Session = scoped_session(sessionmaker(autoflush=True,
  transactional=True, bind=engine))
  metadata = MetaData()
  mapper = Session.mapper

  time_zones = Table('time_zones', metadata,
                  Column('id', Integer, primary_key=True),
                  Column('name', String(35)))

  contacts = Table('contacts', metadata,
                  Column('id', Integer, primary_key=True),
                  Column('display_as', String(35)),
                  Column('time_zone_id', Integer, ForeignKey
  ('time_zones.id')))

  phone_numbers = Table('phone_numbers', metadata,
                  Column('id', Integer, primary_key=True),
                  Column('number', String(35)),
                  Column('contact_id', Integer, ForeignKey
  ('contacts.id')))

  class TimeZone(object): pass
  class Contact(object): pass
  class PhoneNumber(object): pass

  mapper(TimeZone, time_zones)
  mapper(Contact, contacts, properties={
     'time_zone': relation(TimeZone, backref='contacts'),
     'phone_numbers': relation(PhoneNumber, backref='contact',
  cascade='all, delete-orphan')
  })
  mapper(PhoneNumber, phone_numbers)

  metadata.create_all(bind=engine)

  ##

  Under 0.4 the following code executes fine:

  

  c = Contact(display_as='Fake, User')
  c.time_zone = TimeZone.query.filter_by(name='Africa/Algiers').first()
  ph = PhoneNumber(full='1234567890')
  c.phone_numbers.append(ph)
  Session.commit()

  

  But under 0.5 I receive an orphaned object error (see below for full
  output). I understand that the TimeZone query causes a flush in
  between the creation of the Contact and of the PhoneNumber. Without
  the flush in between (if the TimeZone query line is removed) SA 0.5 is
  correctly able execute the sample script.

  As per this thread (http://groups.google.com/group/sqlalchemy/
  browse_thread/thread/6c71c61bc59223f?tvc=2) I see that a suggested
  remedy is to change the relation to cascade='all' rather than
  cascade='all, delete-orphan'.
  I would prefer not to do this as it really does make no sense in this
  case to have a PhoneNumber without a Contact. I could also set the
  relation via 'ph.contact = contact' but I would prefer to not have to
  comb all of our existing code for this new class of bug.

  What doesn't make sense to me is why 0.4 was able to correctly delay
  the insert of the new phone number record until after the query for
  the collection and now 0.5 can't.

  Thank you for the assistance
  -Brad

  Below is the full echo output of 0.4 and 0.5

  0.4.8dev_r5095:
  2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
  BEGIN
  2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
  INSERT INTO contacts (display_as, time_zone_id) VALUES (?, ?)
  2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
  ['Fake, User', None]
  2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
  SELECT time_zones.id AS time_zones_id, time_zones.name AS
  time_zones_name FROM time_zones WHERE time_zones.name = ? ORDER BY
  time_zones.oid LIMIT 1 OFFSET 0
  2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
  ['Africa/Algiers']
  2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
  SELECT phone_numbers.id AS phone_numbers_id, phone_numbers.number AS
  phone_numbers_number, phone_numbers.contact_id AS
  phone_numbers_contact_id FROM phone_numbers WHERE
  phone_numbers.contact_id = ? ORDER BY phone_numbers.oid
  2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70 [4]
  2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
  INSERT INTO phone_numbers (number, contact_id) VALUES (?, ?)
  2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
  [None, 4]
  2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
  COMMIT

  0.5.4p2:
  sa_test.py:8: SADeprecationWarning: The 'transactional

[sqlalchemy] AttributeError: '_ProxyImpl' object has no attribute 'get_history'

2009-07-08 Thread Brad Wells

I receive AttributeError: '_ProxyImpl' object has no attribute
'get_history' when attempting to use session.is_modified  on a class
with a synonym with a descriptor. Removing the descriptor from the
synonym prevents the error. Code and full traceback below.

#
from sqlalchemy import Table, Column, Integer, String, MetaData,
create_engine, ForeignKey
from sqlalchemy.orm import relation, sessionmaker, scoped_session,
mapper, synonym, object_session
from sqlalchemy.orm.interfaces import MapperExtension


class SynonymProp(object):
def __init__(self, attribute):
self._attribute = attribute

def __set__(s, obj, value):
setattr(obj, s._attribute, value)
def __delete__(s, obj):
delattr(obj, s._attribute)
def __get__(s, obj, owner):
if obj is None:
return s
return getattr(obj, s._attribute)

class Extension(MapperExtension):

def before_update(self, mapper, connection, instance):
object_session(instance).is_modified(instance,
include_collections=False)


engine = create_engine('sqlite:///', echo=False)

Session = scoped_session(sessionmaker(autoflush=True,
autocommit=False, bind=engine))
metadata = MetaData()

bananas = Table('bananas', metadata,
   Column('id', Integer, primary_key=True),
   Column('name', String(35)))

class Banana(object): pass

mapper(Banana, bananas, extension=Extension(), properties={
'name': synonym('_name', map_column=True, descriptor=SynonymProp
('_name'))
})

metadata.create_all(bind=engine)

b1 = Banana()
Session.add(b1)
Session.commit()

b1.name = 'Bob'

Session.commit()
#



Traceback (most recent call last):
  File sa_test.py, line 50, in module
Session.commit()
  File c:\program files\python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\scoping.py, line 121, in do
return getattr(self.registry(), name)(*args, **kwargs)
  File C:\PROGRA~1\Python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\session.py, line 673, in commit
self.transaction.commit()
  File C:\PROGRA~1\Python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\session.py, line 378, in commit
self._prepare_impl()
  File C:\PROGRA~1\Python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\session.py, line 362, in _prepare_impl
self.session.flush()
  File C:\PROGRA~1\Python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\session.py, line 1354, in flush
self._flush(objects)
  File C:\PROGRA~1\Python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\session.py, line 1432, in _flush
flush_context.execute()
  File c:\program files\python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\unitofwork.py, line 257, in execute
UOWExecutor().execute(self, tasks)
  File c:\program files\python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\unitofwork.py, line 720, in execute
self.execute_save_steps(trans, task)
  File c:\program files\python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\unitofwork.py, line 735, in
execute_save_steps
self.save_objects(trans, task)
  File c:\program files\python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\unitofwork.py, line 726, in save_objects
task.mapper._save_obj(task.polymorphic_tosave_objects, trans)
  File c:\program files\python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\mapper.py, line 1251, in _save_obj
mapper.extension.before_update(mapper, connection, state.obj())
  File c:\program files\python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\util.py, line 234, in _do
ret = getattr(ext, method)(*args, **kwargs)
  File sa_test.py, line 22, in before_update
object_session(instance).is_modified(instance,
include_collections=False)
  File C:\PROGRA~1\Python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\session.py, line 1483, in is_modified
(added, unchanged, deleted) = attr.get_history(instance,
passive=passive)
  File C:\PROGRA~1\Python\lib\site-packages\sqlalchemy-0.5.4p2-
py2.5.egg\sqlalchemy\orm\attributes.py, line 108, in get_history
return self.impl.get_history(instance_state(instance),
instance_dict(instance), **kwargs)
AttributeError: '_ProxyImpl' object has no attribute 'get_history'
--~--~-~--~~~---~--~~
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 
sqlalchemy+unsubscr...@googlegroups.com
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en
-~--~~~~--~~--~--~---



[sqlalchemy] 0.4 to 0.5 upgrade and 'One-to-many relation fails with unsaved, pending instance and is an orphan' error

2009-07-02 Thread Brad Wells

In the process of upgrading from 0.4 to 0.5 I've come across a
troubling issue. With the following setup:



from sqlalchemy import Table, Column, Integer, String, MetaData,
create_engine, ForeignKey
from sqlalchemy.orm import relation, sessionmaker, scoped_session

engine = create_engine('sqlite:///mystuff.sqlite', echo=True)

Session = scoped_session(sessionmaker(autoflush=True,
transactional=True, bind=engine))
metadata = MetaData()
mapper = Session.mapper

time_zones = Table('time_zones', metadata,
 Column('id', Integer, primary_key=True),
 Column('name', String(35)))

contacts = Table('contacts', metadata,
 Column('id', Integer, primary_key=True),
 Column('display_as', String(35)),
 Column('time_zone_id', Integer, ForeignKey
('time_zones.id')))

phone_numbers = Table('phone_numbers', metadata,
 Column('id', Integer, primary_key=True),
 Column('number', String(35)),
 Column('contact_id', Integer, ForeignKey
('contacts.id')))

class TimeZone(object): pass
class Contact(object): pass
class PhoneNumber(object): pass

mapper(TimeZone, time_zones)
mapper(Contact, contacts, properties={
'time_zone': relation(TimeZone, backref='contacts'),
'phone_numbers': relation(PhoneNumber, backref='contact',
cascade='all, delete-orphan')
})
mapper(PhoneNumber, phone_numbers)

metadata.create_all(bind=engine)

##

Under 0.4 the following code executes fine:




c = Contact(display_as='Fake, User')
c.time_zone = TimeZone.query.filter_by(name='Africa/Algiers').first()
ph = PhoneNumber(full='1234567890')
c.phone_numbers.append(ph)
Session.commit()



But under 0.5 I receive an orphaned object error (see below for full
output). I understand that the TimeZone query causes a flush in
between the creation of the Contact and of the PhoneNumber. Without
the flush in between (if the TimeZone query line is removed) SA 0.5 is
correctly able execute the sample script.

As per this thread (http://groups.google.com/group/sqlalchemy/
browse_thread/thread/6c71c61bc59223f?tvc=2) I see that a suggested
remedy is to change the relation to cascade='all' rather than
cascade='all, delete-orphan'.
I would prefer not to do this as it really does make no sense in this
case to have a PhoneNumber without a Contact. I could also set the
relation via 'ph.contact = contact' but I would prefer to not have to
comb all of our existing code for this new class of bug.

What doesn't make sense to me is why 0.4 was able to correctly delay
the insert of the new phone number record until after the query for
the collection and now 0.5 can't.

Thank you for the assistance
-Brad


Below is the full echo output of 0.4 and 0.5

0.4.8dev_r5095:
2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
BEGIN
2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
INSERT INTO contacts (display_as, time_zone_id) VALUES (?, ?)
2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
['Fake, User', None]
2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
SELECT time_zones.id AS time_zones_id, time_zones.name AS
time_zones_name FROM time_zones WHERE time_zones.name = ? ORDER BY
time_zones.oid LIMIT 1 OFFSET 0
2009-07-02 18:51:17,391 INFO sqlalchemy.engine.base.Engine.0x..70
['Africa/Algiers']
2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
SELECT phone_numbers.id AS phone_numbers_id, phone_numbers.number AS
phone_numbers_number, phone_numbers.contact_id AS
phone_numbers_contact_id FROM phone_numbers WHERE
phone_numbers.contact_id = ? ORDER BY phone_numbers.oid
2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70 [4]
2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
INSERT INTO phone_numbers (number, contact_id) VALUES (?, ?)
2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
[None, 4]
2009-07-02 18:51:17,407 INFO sqlalchemy.engine.base.Engine.0x..70
COMMIT




0.5.4p2:
sa_test.py:8: SADeprecationWarning: The 'transactional' argument to
sessionmaker() is deprecated; use autocommit=True|False instead.
  Session = scoped_session(sessionmaker(autoflush=True,
transactional=True, bind=engine))
2009-07-02 18:54:41,658 INFO sqlalchemy.engine.base.Engine.0x...2f30
PRAGMA table_info(time_zones)
2009-07-02 18:54:41,658 INFO sqlalchemy.engine.base.Engine.0x...2f30
()
2009-07-02 18:54:41,658 INFO sqlalchemy.engine.base.Engine.0x...2f30
PRAGMA table_info(contacts)
2009-07-02 18:54:41,658 INFO sqlalchemy.engine.base.Engine.0x...2f30
()
2009-07-02 18:54:41,658 INFO sqlalchemy.engine.base.Engine.0x...2f30
PRAGMA table_info(phone_numbers)
2009-07-02 18:54:41,658 INFO sqlalchemy.engine.base.Engine.0x...2f30
()
2009-07-02 18:54:41,658 INFO 

[sqlalchemy] AttributeError: 'property' object has no attribute 'impl'

2008-08-18 Thread Brad Wells

I receive the following error with SA 0.4.7p1 and the latest 0.4 svn
revision.

AttributeError: 'property' object has no attribute 'impl'

Mappers
==

mapper(TransactionType, transaction_types)

transactions_mapper = mapper(Transaction, transactions,
order_by=transactions.c.date,
extension=[HistoryMapperExtension(),
TransactionDateMapperExtension()],
polymorphic_on=transactions.c.transaction_type_id,
polymorphic_identity=0,
exclude_properties=['number', 'address', 'shipping',
'handling', 'purchase_order',
'contact_note', 'notes', 'valid_until'],
properties={
'_voided_at': transactions.c.voided_at,
'_date': transactions.c.date,
'method': relation(PaymentMethodType,
backref='transactions'),
'transaction_type': relation(TransactionType,
backref='transactions'),
'created_by_id': transactions.c.created_by,
'updated_by_id': transactions.c.updated_by,
'created_by': relation(Contact,
primaryjoin=transactions.c.created_by==contacts.c.id),
'updated_by': relation(Contact,
primaryjoin=transactions.c.updated_by==contacts.c.id),
})

mapper(Cost, inherits=transactions_mapper, polymorphic_identity=1,
properties={
'line_items': relation(LineItem, backref='cost',
cascade='delete')
})
mapper(Payment, inherits=transactions_mapper,
polymorphic_identity=2)

mapper(Receipt, inherits=transactions_mapper,
polymorphic_identity=4)
mapper(Adjustment, inherits=transactions_mapper,
polymorphic_identity=5)

abstract_sales_mapper = mapper(AbstractSale,
inherits=transactions_mapper,
 
polymorphic_on=transactions.c.transaction_type_id,
   properties={
'number': transactions.c.number,
'address': transactions.c.address,
'shipping': transactions.c.shipping,
'handling': transactions.c.handling,
'purchase_order': transactions.c.purchase_order,
'contact_note': transactions.c.contact_note,
'notes': transactions.c.notes,
'payment_terms': relation(PaymentTerm,
backref='abstract_sales'),
'line_items': relation(LineItem, backref='sale',
cascade='delete', order_by=line_items.c.position)
})

mapper(Sale, inherits=abstract_sales_mapper,
polymorphic_identity=3)

mapper(Quote, inherits=abstract_sales_mapper,
polymorphic_identity=6, properties={
'_valid_until':
transactions.c.valid_until
})


The error occurs when performing a query on Transaction ex:
Transaction.query.get(111)
where row id 111 is a Quote type. If a query uses the specific class
type ex: Quote.query.get(111)
it completes successfully.

I don't know if this is an SA bug or an error in my mappers. Any help
is appreciated.

-brad




Full Traceback
===
In [53]: m.Transaction.query.get(112)
ERROR: An unexpected error occurred while tokenizing input
The following traceback may be corrupted or invalid
The error message is: ('EOF in multi-line statement', (141, 0))

---
AttributeErrorTraceback (most recent call
last)

C:\Documents and Settings\bwells\workspace\ERP GIT TEST\erp\ipython
console in module()

C:\Program Files\Python\lib\site-packages\sqlalchemy-0.4.7p1-py2.5.egg
\sqlalchemy\orm\query.pyc in get(self, ident, **kw
args)
267
268 key = self.mapper.identity_key_from_primary_key(ident)
-- 269 return self._get(key, ident, **kwargs)
270
271 def load(self, ident, raiseerr=True, **kwargs):

C:\Program Files\Python\lib\site-packages\sqlalchemy-0.4.7p1-py2.5.egg
\sqlalchemy\orm\query.pyc in _get(self, key, ident
, refresh_instance, lockmode, only_load_props)
   1066 try:
   1067 # call using all() to avoid LIMIT compilation
complexity
- 1068 return q.all()[0]
   1069 except IndexError:
   1070 return None

C:\Program Files\Python\lib\site-packages\sqlalchemy-0.4.7p1-py2.5.egg
\sqlalchemy\orm\query.pyc in all(self)
876
877 
-- 878 return list(self)
879
880

C:\Program Files\Python\lib\site-packages\sqlalchemy-0.4.7p1-py2.5.egg
\sqlalchemy\orm\query.pyc in iterate_instances(sel
f, cursor, *mappers_or_columns, **kwargs)
   1001 rows = []
   1002 for row in fetch:
- 1003 process[0](context, row, rows)
   1004 elif single_entity:
   1005 rows = [process[0](context, row) for row in
fetch]

C:\Program Files\Python\lib\site-packages\sqlalchemy-0.4.7p1-py2.5.egg
\sqlalchemy\orm\query.pyc in main(context, row, re
sult)
   1579 row = context.row_adapter(row)
   1580 self.mapper._instance(context, row, result,
- 1581 extension=context.extension,
only_load_props=context.only_load_props, refresh_instance=conte

[sqlalchemy] Orphan error

2008-06-06 Thread Brad Wells

With the following simplified setup I receive the following error:

FlushError: instance erp.model.financial.TransactionOffset object at
0x0203CC90 is an unsaved, pending instance and is an orphan (is not
attached to any parent 'Transaction' instance via that classes'
'offsets' attribute)

When attempting something along the lines of

transactions = Transaction.query.all()
offset = TransactionOffset()
offset.transaction = transactions[4]
offset.offset_transaction = transactions[5]
meta.Session.commit()

However, if I append offset to transactions[4].offsets it will save
transaction_id, but not offset_transaction_id

Classes:
class Transaction(Entity):
pass

class TransactionOffset(Entity):
pass

Tables:

transactions = Table('transactions', meta,
Column('id', Integer, primary_key=True),
Column('date', Date),
Column('description', Text),
Column('amount', Float),
Column('transaction_code', String(50)),
Column('approval_code', String(50)),
Column('voided_at', DateTime),
)

transaction_offsets = Table('transaction_offsets', meta,
Column('id', Integer, primary_key=True),
Column('amount', Float),
Column('transaction_id', Integer),
Column('offset_transaction_id', Integer),
ForeignKeyConstraint(['transaction_id'], ['transactions.id']),
ForeignKeyConstraint(['offset_transaction_id'],
['transactions.id']),
)

Mappers:

transactions_mapper = mapper(Transaction, transactions, properties={
'offsets': relation(TransactionOffset,
primaryjoin=transaction_offsets.c.transaction_id==transactions.c.id,
cascade='all, delete-
orphan'),
})

mapper(TransactionOffset, transaction_offsets, properties={
'transaction': relation(Transaction,
primaryjoin=transaction_offsets.c.transaction_id==transactions.c.id,
post_update=True),
'offset_transaction': relation(Transaction,
primaryjoin=transaction_offsets.c.offset_transaction_id==transactions.c.id,
post_update=True),
})

-brad
--~--~-~--~~~---~--~~
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: Unknown inheritance type question

2008-06-05 Thread Brad Wells

Thank you very much. again.

-brad

On Jun 5, 10:57 am, Michael Bayer [EMAIL PROTECTED] wrote:
 this mapping:

 transaction_sale_join = join(transactions, sales)
 mapper(Sale, transaction_sale_join, inherits=transactions_mapper,
  polymorphic_identity=3, properties={
 'line_items': relation(LineItem, backref='sale', cascade='all,
  delete-orphan')
 })

 is incorrect.  The inherits configuration will create the join from
 transactions-sales for you - Sale should be mapped directly to sales.

 On Jun 4, 2008, at 6:29 PM, Brad Wells wrote:



  The complexity of the following setup is that of the transaction type
  Sales also have their own table. I am unsure of how properly establish
  this relationship between Transactions, Sales and TransactionTypes.

  This setup so far allows me to create Sale objects and save them.
  However Sale.query.all() (for example) results in: OperationalError:
  (OperationalError) (1066, Not unique table/alias: 'transactions')

  any advice is appreciated.

  Tables:

  transactions = Table('transactions', meta,
 Column('id', Integer, primary_key=True),
 Column('transaction_type_id', Integer),
 ForeignKeyConstraint(['transaction_type_id'],
  ['transaction_types.id']),
  )

  transaction_types = Table('transaction_types', meta,
 Column('id', Integer, primary_key=True),
 Column('name', String(15)),
 Column('has_line_items', Boolean),
  )

  sales = Table('sales', meta,
 Column('id', Integer, primary_key=True),
 Column('address', Text),
 Column('shipping', Float),
 Column('handling', Float),
 Column('purchase_order', String(35)),
 Column('transaction_id', Integer),
 ForeignKeyConstraint(['transaction_id'], ['transactions.id']),
  )

  line_items = Table('line_items', meta,
 Column('id', Integer, primary_key=True),
 Column('position', Integer),
 Column('description', Text),
 Column('quantity', Float),
 Column('units', String(15)),
 Column('unit_rate', Float),
 Column('tax', Float),
 Column('transaction_id', Integer),
 ForeignKeyConstraint(['transaction_id'], ['transactions.id']),
  )

  Classes:

  class Transaction(Entity):
 pass

  class TransactionType(Entity):
 pass

  class Payment(Transaction):
 pass

  class Adjustment(Transaction):
 pass

  class Receipt(Transaction):
 pass

  # abstract class
  class LineItemTransaction(Transaction):
 pass

  class Cost(LineItemTransaction):
 pass

  class Sale(LineItemTransaction):
 pass

  class LineItem(Entity):
 pass

  Mappers:

 mapper(TransactionType, transaction_types)

 transactions_mapper = mapper(Transaction, transactions,
 polymorphic_on=transactions.c.transaction_type_id,
  polymorphic_identity=0,
 properties={
 'transaction_type': relation(TransactionType,
  backref='transactions'),
 })

 mapper(Cost, inherits=transactions_mapper, polymorphic_identity=1,
  properties={
 'line_items': relation(LineItem, backref='cost', cascade='all,
  delete-orphan')
 })
 mapper(Payment, inherits=transactions_mapper,
  polymorphic_identity=2)

 mapper(Receipt, inherits=transactions_mapper,
  polymorphic_identity=4)

 mapper(Adjustment, inherits=transactions_mapper,
  polymorphic_identity=5)

 transaction_sale_join = join(transactions, sales)
 mapper(Sale, transaction_sale_join, inherits=transactions_mapper,
  polymorphic_identity=3, properties={
 'line_items': relation(LineItem, backref='sale', cascade='all,
  delete-orphan')
 })

 mapper(LineItem, line_items)

  -brad
--~--~-~--~~~---~--~~
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] Unknown inheritance type question

2008-06-04 Thread Brad Wells

The complexity of the following setup is that of the transaction type
Sales also have their own table. I am unsure of how properly establish
this relationship between Transactions, Sales and TransactionTypes.

This setup so far allows me to create Sale objects and save them.
However Sale.query.all() (for example) results in: OperationalError:
(OperationalError) (1066, Not unique table/alias: 'transactions')

any advice is appreciated.

Tables:

transactions = Table('transactions', meta,
Column('id', Integer, primary_key=True),
Column('transaction_type_id', Integer),
ForeignKeyConstraint(['transaction_type_id'],
['transaction_types.id']),
)

transaction_types = Table('transaction_types', meta,
Column('id', Integer, primary_key=True),
Column('name', String(15)),
Column('has_line_items', Boolean),
)

sales = Table('sales', meta,
Column('id', Integer, primary_key=True),
Column('address', Text),
Column('shipping', Float),
Column('handling', Float),
Column('purchase_order', String(35)),
Column('transaction_id', Integer),
ForeignKeyConstraint(['transaction_id'], ['transactions.id']),
)

line_items = Table('line_items', meta,
Column('id', Integer, primary_key=True),
Column('position', Integer),
Column('description', Text),
Column('quantity', Float),
Column('units', String(15)),
Column('unit_rate', Float),
Column('tax', Float),
Column('transaction_id', Integer),
ForeignKeyConstraint(['transaction_id'], ['transactions.id']),
)

Classes:

class Transaction(Entity):
pass

class TransactionType(Entity):
pass

class Payment(Transaction):
pass


class Adjustment(Transaction):
pass


class Receipt(Transaction):
pass


# abstract class
class LineItemTransaction(Transaction):
pass

class Cost(LineItemTransaction):
pass

class Sale(LineItemTransaction):
pass

class LineItem(Entity):
pass

Mappers:

mapper(TransactionType, transaction_types)

transactions_mapper = mapper(Transaction, transactions,
polymorphic_on=transactions.c.transaction_type_id,
polymorphic_identity=0,
properties={
'transaction_type': relation(TransactionType,
backref='transactions'),
})

mapper(Cost, inherits=transactions_mapper, polymorphic_identity=1,
properties={
'line_items': relation(LineItem, backref='cost', cascade='all,
delete-orphan')
})
mapper(Payment, inherits=transactions_mapper,
polymorphic_identity=2)

mapper(Receipt, inherits=transactions_mapper,
polymorphic_identity=4)

mapper(Adjustment, inherits=transactions_mapper,
polymorphic_identity=5)

transaction_sale_join = join(transactions, sales)
mapper(Sale, transaction_sale_join, inherits=transactions_mapper,
polymorphic_identity=3, properties={
'line_items': relation(LineItem, backref='sale', cascade='all,
delete-orphan')
})

mapper(LineItem, line_items)

-brad

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