[sqlalchemy] Re: Polymorphic mappers on boolean types
Yeah once I'd worked it out I converted the field over to being an int field, just didn't see this one coming :-) Maybe something worth adding into the doco if it's going to stick around ? On Monday 07 January 2008 02:03:19 Michael Bayer wrote: yeah thats line 1303 of mapper.py. i think i might have made that change right in 0.4.2 thinking, nobody would use a boolean False as a discriminatorany chance you can go with some plain int or string for that ? On Jan 5, 2008, at 11:47 PM, Dave Harrison wrote: Hey all, More fun with inheritance and mappers. In the following situation where the polymorphic type is a Boolean, the mapper for the object that matches on False incorrectly returns the parent object. Cheers Dave -- -- testapi.py -- from sqlalchemy import * from sqlalchemy.orm import * session = scoped_session( sessionmaker(autoflush=False, transactional=True) ) mapper = session.mapper metadata = MetaData() ANIMAL_TYPE_DOG = True ANIMAL_TYPE_CAT = False VET_TYPE_CITY = 1 VET_TYPE_COUNTRY = 2 animalTable = Table( 'animal', metadata, Column('id', Integer, primary_key=True), Column('type', Boolean, nullable=False), Column('name', String(100), nullable=False), Column('vet_id', Integer, ForeignKey('vet.id')), ) vetTable = Table( 'vet', metadata, Column('id', Integer, primary_key=True), Column('address', String(100), nullable=False), Column('kennel', Boolean, nullable=False), ) class _Animal(object): pass class Cat(_Animal): pass class Dog(_Animal): pass class Vet(object): pass vetMapper = mapper( Vet, vetTable, properties = { animals: relation( _Animal, backref=backref(vet, uselist=False), cascade=all, delete-orphan ), } ) animalMapper = mapper( _Animal, animalTable, polymorphic_on=animalTable.c.type, ) mapper( Dog, inherits=animalMapper, polymorphic_identity=ANIMAL_TYPE_DOG, ) mapper( Cat, inherits=animalMapper, polymorphic_identity=ANIMAL_TYPE_CAT, ) def connect(uri): engine = create_engine(uri, strategy=threadlocal) metadata.bind = engine return engine def create(): metadata.create_all() def drop(): metadata.drop_all() -- -- test.py -- import sys import testapi as db DB = sqlite:///memory db.connect(DB) db.create() v = db.Vet() v.address = 12 Foo St v.kennel = True c1 = db.Cat() c1.name = muffin c2 = db.Cat() c2.name = bagel d1 = db.Dog() d1.name = rex d2 = db.Dog() d2.name = bill db.session.flush() db.session.clear() for d in db.Query(db.Dog).all(): v.animals.append(d) for c in db.Query(db.Cat).all(): v.animals.append(c) db.session.flush() db.session.clear() v = db.Query(db.Vet).first() for a in v.animals: print a --~--~-~--~~~---~--~~ 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: Emptying out the session of new objects
On Sunday 06 January 2008 05:30:04 Michael Bayer wrote: On Jan 4, 2008, at 9:46 PM, Dave Harrison wrote: Hey Mike, Below is a minimal test case that always produces the below failure for me under 0.4.2 but not under 0.4.1, OK, its actually something that was buggy in 0.4.1 but didnt produce a symptom, give r4003 a try which fixes this issue...0.4.2a is today Hi Mike, That seems to have solved it for me. Thanks for the quick turn around, SQLAlchemy and the team continue to amaze ! :-) Cheers Dave --~--~-~--~~~---~--~~ 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] Polymorphic mappers on boolean types
Hey all, More fun with inheritance and mappers. In the following situation where the polymorphic type is a Boolean, the mapper for the object that matches on False incorrectly returns the parent object. Cheers Dave -- -- testapi.py -- from sqlalchemy import * from sqlalchemy.orm import * session = scoped_session( sessionmaker(autoflush=False, transactional=True) ) mapper = session.mapper metadata = MetaData() ANIMAL_TYPE_DOG = True ANIMAL_TYPE_CAT = False VET_TYPE_CITY = 1 VET_TYPE_COUNTRY = 2 animalTable = Table( 'animal', metadata, Column('id', Integer, primary_key=True), Column('type', Boolean, nullable=False), Column('name', String(100), nullable=False), Column('vet_id', Integer, ForeignKey('vet.id')), ) vetTable = Table( 'vet', metadata, Column('id', Integer, primary_key=True), Column('address', String(100), nullable=False), Column('kennel', Boolean, nullable=False), ) class _Animal(object): pass class Cat(_Animal): pass class Dog(_Animal): pass class Vet(object): pass vetMapper = mapper( Vet, vetTable, properties = { animals: relation( _Animal, backref=backref(vet, uselist=False), cascade=all, delete-orphan ), } ) animalMapper = mapper( _Animal, animalTable, polymorphic_on=animalTable.c.type, ) mapper( Dog, inherits=animalMapper, polymorphic_identity=ANIMAL_TYPE_DOG, ) mapper( Cat, inherits=animalMapper, polymorphic_identity=ANIMAL_TYPE_CAT, ) def connect(uri): engine = create_engine(uri, strategy=threadlocal) metadata.bind = engine return engine def create(): metadata.create_all() def drop(): metadata.drop_all() -- -- test.py -- import sys import testapi as db DB = sqlite:///memory db.connect(DB) db.create() v = db.Vet() v.address = 12 Foo St v.kennel = True c1 = db.Cat() c1.name = muffin c2 = db.Cat() c2.name = bagel d1 = db.Dog() d1.name = rex d2 = db.Dog() d2.name = bill db.session.flush() db.session.clear() for d in db.Query(db.Dog).all(): v.animals.append(d) for c in db.Query(db.Cat).all(): v.animals.append(c) db.session.flush() db.session.clear() v = db.Query(db.Vet).first() for a in v.animals: print a --~--~-~--~~~---~--~~ 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] Emptying out the session of new objects
Hey all, I'm unit testing my DB api's, and I've found that if I don't explicitly expunge my objects from the session at the end of each test, I get objects left over in the session when the next test runs. Is there an easy way of flushing all objects that are categorised as new in the session ?? Cheers Dave --~--~-~--~~~---~--~~ 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: Emptying out the session of new objects
On Friday 04 January 2008 23:32:21 Alexandre da Silva wrote: Is there an easy way of flushing all objects that are categorised as new in the session ?? I think you can use session.clear(), it will remove objects from session, and persistent objects will stay on database. Att Alexandre I had been using session.clear up until now, but as of 0.4.2 I've found that I get this error for alot of my tests, object has no attribute '_sa_session_id' As background, the tests I have use a sqlite memory database, and on setUp do a meta.create_all and on tearDown do a meta.drop_all I've assumed that this error is due to me leaving objects around in the session, so my current theory is that I need to manually expunge the objects I create at the end of the test. --~--~-~--~~~---~--~~ 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: Emptying out the session of new objects
On Saturday 05 January 2008 03:08:54 Michael Bayer wrote: On Jan 4, 2008, at 7:44 AM, Dave Harrison wrote: On Friday 04 January 2008 23:32:21 Alexandre da Silva wrote: Is there an easy way of flushing all objects that are categorised as new in the session ?? I think you can use session.clear(), it will remove objects from session, and persistent objects will stay on database. Att Alexandre I had been using session.clear up until now, but as of 0.4.2 I've found that I get this error for alot of my tests, object has no attribute '_sa_session_id' thats a bug. can you please provide a reproducing test case ? this is actually pretty serious and a new release will be available the moment we fix this. Hey Mike, Below is a minimal test case that always produces the below failure for me under 0.4.2 but not under 0.4.1, Cheers Dave == ERROR: test_repr (__main__.uScheduledEvent) -- Traceback (most recent call last): File ./test_db_minimal.py, line 19, in tearDown db.session.clear() File /usr/local/lib/python2.5/site-packages/SQLAlchemy-0.4.2-py2.5.egg/sqlalchemy/orm/scoping.py, line 74, in do return getattr(self.registry(), name)(*args, **kwargs) File /usr/local/lib/python2.5/site-packages/SQLAlchemy-0.4.2-py2.5.egg/sqlalchemy/orm/session.py, line 577, in clear self._unattach(instance) File /usr/local/lib/python2.5/site-packages/SQLAlchemy-0.4.2-py2.5.egg/sqlalchemy/orm/session.py, line 1039, in _unattach if instance._sa_session_id == self.hash_key: AttributeError: 'MonthlyEvent' object has no attribute '_sa_session_id' -- dbapi_minimal.py -- import datetime, uuid from sqlalchemy import * from sqlalchemy.orm import * session = scoped_session(sessionmaker(autoflush=False, transactional=True)) mapper = session.mapper metadata = MetaData() ## Static variables and mappings EventType_Daily = 0 EventType_Weekly = 1 EventType_Monthly = 2 EventType_Yearly = 3 eventTable = Table( 'event', metadata, Column('id', Integer, primary_key=True), Column('name', String(100), nullable=False, unique=True), Column('type', Integer, nullable=False), Column('action', BLOB), # Pickled arguments for running an action Column('step', Integer, nullable=False, default=1), Column('fromDate', DateTime), # None indicates now Column('untilDate', DateTime), # None indicates forever Column('monthly_dayofweek', Boolean), ) scheduledEventTable = Table( 'scheduledevent', metadata, Column('id', Integer, primary_key=True), Column('event_id', Integer, ForeignKey('event.id')), Column('runtime', DateTime), ) class Event(object): def __init__(self, name, action, step=1, fromDate=None, untilDate=None): action: Pickled ActionArgument object for running the event fromDate : First time to run this event untilDate : Time at which this event is no longer valid self.name = name self.action = action self.step = step self.fromDate = fromDate self.untilDate = untilDate def next(self, last): last: most recent timestamp when this event was executed raise NotImplementedError(Events must provide a next()) def __repr__(self): return Event type:%s id:%s % (self.typeName, self.id) class MonthlyEvent(Event): MonthlyEvent has an additional init arg of dayofweek. E.G if (dayofweek == True) then do every first Monday E.G if (dayofweek == False) then do every nth day of the month [beware choosing a day 28 lest some months skip it] def __init__(self, name, action, step=1, fromDate=None, untilDate=None, dayofweek=True): Event.__init__(self, name, action, step, fromDate, untilDate) self.dayofweek = dayofweek def next(self, last): monthQuot,monthRem = divmod((last.month + self.step), 12) # Div cycles to 0, so we need to handle this differently # 0 indicates December in the current year if monthRem == 0: monthRem = 12 monthQuot = 0 incMonth = monthRem incYear = last.year + monthQuot newTS = datetime.datetime( year = incYear, month = incMonth, day = last.day, hour = self.fromDate.hour, minute = self.fromDate.minute, ) if newTS self.untilDate: return None return newTS class ScheduledEvent(object): This is an event that is waiting for its runtime to arrive def __init__(self, event, runtime): self.event = event
[sqlalchemy] Mapper inheritance and joins
Hi all, I've got a situation where I want to use inherited mappers, with joins to other inherited mappers. However I'm getting some weird results where the following query should show no cat objects, instead I get 2 back for both queries. Can anyone spot the flaw in my code here ? The api and test script are transcribed below. Cheers D --- testapi.py #!/usr/local/bin/python2.5 from sqlalchemy import * from sqlalchemy.orm import * session = scoped_session( sessionmaker(autoflush=False, transactional=True) ) mapper = session.mapper metadata = MetaData() ANIMAL_TYPE_DOG = 1 ANIMAL_TYPE_CAT = 2 animalTable = Table( 'animal', metadata, Column('id', Integer, primary_key=True), Column('type', Integer, nullable=False), Column('name', String(100), nullable=False), Column('vet_id', Integer, ForeignKey('vet.id')), ) vetTable = Table( 'vet', metadata, Column('id', Integer, primary_key=True), Column('type', Integer, nullable=False), Column('address', String(100), nullable=False), Column('kennel', Boolean, nullable=False), ) class _Animal(object): def printName(self): print self.name class Cat(_Animal): pass class Dog(_Animal): pass class _Vet(object): def printAddress(self): print self.address class CatVet(_Vet): pass class DogVet(_Vet): pass animalMapper = mapper( _Animal, animalTable, polymorphic_on=animalTable.c.type, ) mapper( Dog, inherits=animalMapper, polymorphic_identity=ANIMAL_TYPE_DOG, properties = { vet: relation( DogVet, lazy=False, ) } ) mapper( Cat, inherits=animalMapper, polymorphic_identity=ANIMAL_TYPE_CAT, properties = { vet: relation( CatVet, lazy=False, ) } ) vetMapper = mapper( _Vet, vetTable, polymorphic_on=vetTable.c.type, ) mapper( DogVet, inherits=vetMapper, polymorphic_identity=ANIMAL_TYPE_DOG, ) mapper( CatVet, inherits=vetMapper, polymorphic_identity=ANIMAL_TYPE_CAT, ) def connect(uri): engine = create_engine(uri, strategy=threadlocal) metadata.bind = engine return engine def create(): metadata.create_all() def drop(): metadata.drop_all() test.py #!/usr/local/bin/python2.5 import testapi as db DB = sqlite:///test.db db.connect(DB) db.create() v1 = db.DogVet() v1.address = 12 Foo St v1.kennel = True v2 = db.CatVet() v2.address = 29 Bar Rd v2.kennel = False v3 = db.CatVet() v3.address = 29 Bar Rd v3.kennel = True c1 = db.Cat() c1.name = muffin c1.vet = v2 c2 = db.Cat() c2.name = bagel c2.vet = v2 d1 = db.Dog() d1.name = rex d1.vet = v1 d2 = db.Dog() d2.name = bill d2.vet = v1 db.session.flush() print db.Query(db.Cat).filter(db.CatVet.kennel == True).all() print db.Query(db.Cat).filter(db.CatVet.kennel == False).all() db.drop() db.session.flush() --~--~-~--~~~---~--~~ 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] Mapper properties and a callback
Hi all, I have a situation where I want to declare a relation between two tables, but I want to be able to run a callback whenever I append to that relation. Here's an example class Kennel: def callback(self, o): print callback, o mapper = Mapper( Kennel, kennelTable, properties = { dogs : relation( Dog, cascade=all, delete-orphan ), } ) So whenever I use mykennel.dogs.append(fred) I want to be able to tell the relation to call callback() so that I can do some checking on the object that is being appended. Is this possible ?? Cheers Dave --~--~-~--~~~---~--~~ 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] Deprecation error raised for query on singly inherited table query ?
Hi all, The following is a stripped down use case that I have, where I use single table inheritance and run a query.first(), however I get a deprecation warning and I was wondering why ?? Cheers Dave % cat db.py from sqlalchemy import * from sqlalchemy.orm import * session = scoped_session( sessionmaker( autoflush=False, transactional=True ) ) mapper = session.mapper metadata = MetaData() myTable = Table( 'mytable', metadata, Column('id', Integer, primary_key=True), Column('animate', Boolean, nullable=False), Column('remoteid', String(50), nullable=False), ) class MyTable(object): pass class MyAnimateTable(MyTable): pass myTableMapper = mapper( MyTable, myTable, polymorphic_on=myTable.c.animate ) mapper( MyAnimateTable, inherits=myTableMapper, polymorphic_identity=True, ) def connect(uri): engine = create_engine(uri, strategy=threadlocal) metadata.bind = engine return engine def create(): metadata.create_all() def drop(): metadata.drop_all() % cat test.py from db import * connect('sqlite://memory') drop() create() klass = MyAnimateTable Query(klass).filter(klass.remoteid == fds).first() Deprecation warning: /usr/lib/python2.5/site-packages/SQLAlchemy-0.4.1dev_r3765-py2.5.egg/sqlalchemy/sql/expression.py:1231: SADeprecationWarning: passing in_ arguments as varargs is deprecated, in_ takes a single argument that is a sequence or a selectable return self._in_impl(operators.in_op, operators.notin_op, *other) --~--~-~--~~~---~--~~ 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] 'Column' object has no attribute 'tables'
Hi all, I'm just working on upgrading my db code to use the new 0.4 api, and I've hit a problem Based on the following table def (there's lots more in there, but I've commented everything out but this table and am still getting the same error), sysMessageTable = Table( 'sysmessage', Column('id', Integer, primary_key=True), Column('timestamp', DateTime, nullable=False, default=datetime.datetime.now()), Column('summary', String(100), nullable=False), Column('message', TEXT()), Column('viewed', Boolean, nullable=False, default=False), when I import my db.py file (literally at the time of import), I get this error, Traceback (most recent call last): File scripts/testdata, line 7, in module from mymod.db import * File ./mymod/db.py, line 129, in module Column('viewed', Boolean, nullable=False, default=False), File /usr/lib/python2.5/site-packages/SQLAlchemy-0.4.0dev_r3150-py2.5.egg/sqlalchemy/schema.py, line 146, in __call__ table = metadata.tables[key] AttributeError: 'Column' object has no attribute 'tables' Any suggestions ? Cheers Dave --~--~-~--~~~---~--~~ 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 -~--~~~~--~~--~--~---