[sqlalchemy] before_flush event doesn't seem to permit additional update to dirty objects

2012-06-06 Thread Damian Dimmich

Hi,

I have a before flush event set up that sets the current user_id and 
datetime on new objects that are going to be commited to the database 
(all tables have these fields).


Unfortunately, it seems to ignore changes I make to existing objects, ie 
when I set the user_id (which i get from pyramid) and last_updated 
columns in the event handler, the sql only issues updates for the other 
columns that where modified.


Any ideas as to what am I missing?

Thanks in advance,
Damian


def attach_user_committing(Session, flush_context, instances):
This function gets called by the before_flush event,
it grabs the current threads request and extracts the
authenticated user_id out of it.  You can only
commit things if you are authenticated.

Once it has that id, it goes through and adds the id
of the user who modified it to new commits- need to be careful that
_new doesn't change.


#this is used when creating databases  testing only
user_id = 1
if not creating_database:
user_id = 
authenticated_userid(pyramid.threadlocal.get_current_request())
#for each object being committed/flushed, set the 
flushing/commiting user

for obj in Session._new.values():
#log.debug(obj)
obj.user_id = user_id
obj.last_updated = datetime.now()
log.debug('Session dirty is : %s' %Session.dirty)
for obj in Session.dirty:
log.debug('Objects in dirty: %s' % obj.__dict__)
#if obj._sa_instance_state.modified:
obj.user_id = user_id
obj.last_updated = datetime.now()


#session.user_id = request
#this event ensures that user_id  lastupdate is correctly stored on 
each commit.

event.listen(Session, before_flush, attach_user_committing)

--
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] 'InstanceState' object has no attribute 'manager.mapper', w/ Jython2.7.2

2012-06-06 Thread Alexander Dorsk
Hello All,

I was curious if anyone else has run into this error:

error message

Traceback (most recent call last):
  File util/sa/tests/test_sa_dao.py, line 96, in setUp
self.session.add(tc1)
  File
/home/adorsk/projects/gr/jenv2.7/Lib/site-packages/sqlalchemy/orm/session.py,
line 1251, in add
self._save_or_update_state(state)
  File
/home/adorsk/projects/gr/jenv2.7/Lib/site-packages/sqlalchemy/orm/session.py,
line 1262, in _save_or_update_state
mapper = _state_mapper(state)
AttributeError: 'InstanceState' object has no attribute 'manager.mapper'

/error message

The context in which this error message is generated is pasted below.

I'm using Jython2.7 on a Postgres, via xzJDBC and the Postgresql JDBC
driver.

If you did encounter this error, did you find a workaround?

-Alex

P.S. SqlAlchemy is absolutely brilliant!  Beautiful docs and code,
definitely my new favorite python tool.



code

import unittest

from sqlalchemy import Table, Column, ForeignKey, ForeignKeyConstraint,
Integer, String, Float, MetaData, create_engine
from sqlalchemy.orm import relationship, mapper
from geoalchemy import *
from geoalchemy.postgis import PGComparator
from sqlalchemy.orm import sessionmaker

class My_Test(unittest.TestCase):

def testFoo(self):
print foo

def setUp(self):
self.engine =
create_engine('postgresql+zxjdbc://MY_DB:MY_USER@localhost/MY_PASS)
self.Session = sessionmaker()
connection = self.engine.connect()

# begin a non-ORM transaction
self.trans = connection.begin()

# bind an individual Session to the connection
self.session = self.Session(bind=connection)

schema = {}
self.schema = schema
schema['classes'] = {}

class TestClass1(object):
id = None
children = []
schema['classes']['TestClass1'] = TestClass1

class TestClass2(object):
id = None
name = 
schema['classes']['TestClass2'] = TestClass2

schema['primary_class'] = TestClass1

metadata = MetaData()

test1_table = Table('test1', metadata,
Column('id', Integer, primary_key=True)
)

test2_table = Table('test2', metadata,
Column('id', Integer, primary_key=True),
Column('name', String)
)

test1_test2_table = Table('test1_test2', metadata,
Column('test1_id', Integer, primary_key=True),
Column('test2_id', Integer, primary_key=True),
ForeignKeyConstraint(['test1_id'], [test1_table.c.id]),
ForeignKeyConstraint(['test2_id'], [test2_table.c.id])
)

mapper(
TestClass1,
test1_table,
properties = {
'children': relationship(TestClass2,
secondary=test1_test2_table)
}
)

mapper(
TestClass2,
test2_table,
properties = {
}
)

metadata.create_all(self.session.bind)

tc1s = []
tc2s = []
for i in range(5):
tc1 = TestClass1()
tc1s.append(tc1)
self.session.add(tc1)

tc2 = TestClass2()
tc2.name = tc2_%s % i
tc2s.append(tc2)
self.session.add(tc2)

self.session.commit()

for i in range(len(tc1s)):
tc1 = tc1s[i]
child_tc2s = [tc2s[i], tc2s[ (i + 1) % len(tc1s)]]
for c in child_tc2s:
tc2 = self.session.query(TestClass2).filter(TestClass2.id
== c.id).one()
tc1.children.append(tc2)

self.session.commit()

if __name__ == '__main__':
unittest.main()

/code

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



Re: [sqlalchemy] 'InstanceState' object has no attribute 'manager.mapper', w/ Jython2.7.2

2012-06-06 Thread Michael Bayer
unfortunately issues like these are often resulting from Jython bugs.For 
example, SQLAlchemy was entirely unusable with the previous version of Jython 
due to a bug in their __import__ mechanism.  That the test works fine using 
regular cPYthon with psycopg2 further points to some incompatibility/quirk in 
Jython as a potential culprit.   

As a test, since I don't have Jython installed, what does this produce for you ?

class Foo(object):
pass

class Bar(object):
pass

f = Foo()
f.bar = Bar()
f.bar.bat = 5

from operator import attrgetter
print attrgetter(bar.bat)(f)

if you get that same error, then this is the Jython bug - attrgetter() as of 
2.6 handles dotted paths.   SQLAlchemy does have a workaround version for 
Python less than 2.6 which we can also enable for Jython, for the interim, but 
also this should be reported to Jython as a bug.





On Jun 6, 2012, at 10:37 AM, Alexander Dorsk wrote:

 import unittest
 
 from sqlalchemy import Table, Column, ForeignKey, ForeignKeyConstraint, 
 Integer, String, Float, MetaData, create_engine
 from sqlalchemy.orm import relationship, mapper
 from geoalchemy import *
 from geoalchemy.postgis import PGComparator
 from sqlalchemy.orm import sessionmaker
 
 class My_Test(unittest.TestCase):
 
 def testFoo(self):
 print foo
 
 def setUp(self):
 self.engine = 
 create_engine('postgresql+zxjdbc://MY_DB:MY_USER@localhost/MY_PASS)
 self.Session = sessionmaker()
 connection = self.engine.connect()
 
 # begin a non-ORM transaction
 self.trans = connection.begin()
 
 # bind an individual Session to the connection
 self.session = self.Session(bind=connection)
 
 schema = {}
 self.schema = schema
 schema['classes'] = {}
 
 class TestClass1(object):
 id = None
 children = []
 schema['classes']['TestClass1'] = TestClass1
 
 class TestClass2(object):
 id = None
 name = 
 schema['classes']['TestClass2'] = TestClass2
 
 schema['primary_class'] = TestClass1
 
 metadata = MetaData()
 
 test1_table = Table('test1', metadata,
 Column('id', Integer, primary_key=True)
 )
 
 test2_table = Table('test2', metadata,
 Column('id', Integer, primary_key=True),
 Column('name', String)
 )
 
 test1_test2_table = Table('test1_test2', metadata,
 Column('test1_id', Integer, primary_key=True),
 Column('test2_id', Integer, primary_key=True),
 ForeignKeyConstraint(['test1_id'], [test1_table.c.id]),
 ForeignKeyConstraint(['test2_id'], [test2_table.c.id])
 )
 
 mapper(
 TestClass1,
 test1_table,
 properties = {
 'children': relationship(TestClass2, 
 secondary=test1_test2_table)
 }
 )
 
 mapper(
 TestClass2,
 test2_table,
 properties = {
 }
 )
 
 metadata.create_all(self.session.bind)
 
 tc1s = []
 tc2s = []
 for i in range(5):
 tc1 = TestClass1()
 tc1s.append(tc1)
 self.session.add(tc1)
 
 tc2 = TestClass2()
 tc2.name = tc2_%s % i
 tc2s.append(tc2)
 self.session.add(tc2)
 
 self.session.commit()
 
 for i in range(len(tc1s)):
 tc1 = tc1s[i]
 child_tc2s = [tc2s[i], tc2s[ (i + 1) % len(tc1s)]]
 for c in child_tc2s:
 tc2 = self.session.query(TestClass2).filter(TestClass2.id == 
 c.id).one()
 tc1.children.append(tc2)

 self.session.commit()
 
 if __name__ == '__main__':
 unittest.main()

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



Re: [sqlalchemy] before_flush event doesn't seem to permit additional update to dirty objects

2012-06-06 Thread Michael Bayer
The code looks fine to me, other than the access of Session._new for which you 
should be really calling upon the public new collection.

What you might want to make sure of is that the objects you expect to see in 
dirty are actually there.   Sometimes objects don't make it into dirty 
until they are found to be impacted by a relationship() changing something on 
them.   If this is the case you'd want to navigate to those objects differently.


On Jun 6, 2012, at 6:36 AM, Damian Dimmich wrote:

 Hi,
 
 I have a before flush event set up that sets the current user_id and datetime 
 on new objects that are going to be commited to the database (all tables have 
 these fields).
 
 Unfortunately, it seems to ignore changes I make to existing objects, ie when 
 I set the user_id (which i get from pyramid) and last_updated columns in the 
 event handler, the sql only issues updates for the other columns that where 
 modified.
 
 Any ideas as to what am I missing?
 
 Thanks in advance,
 Damian
 
 
 def attach_user_committing(Session, flush_context, instances):
This function gets called by the before_flush event,
it grabs the current threads request and extracts the
authenticated user_id out of it.  You can only
commit things if you are authenticated.
 
Once it has that id, it goes through and adds the id
of the user who modified it to new commits- need to be careful that
_new doesn't change.

 
#this is used when creating databases  testing only
user_id = 1
if not creating_database:
user_id = 
 authenticated_userid(pyramid.threadlocal.get_current_request())
#for each object being committed/flushed, set the flushing/commiting user
for obj in Session._new.values():
#log.debug(obj)
obj.user_id = user_id
obj.last_updated = datetime.now()
log.debug('Session dirty is : %s' %Session.dirty)
for obj in Session.dirty:
log.debug('Objects in dirty: %s' % obj.__dict__)
#if obj._sa_instance_state.modified:
obj.user_id = user_id
obj.last_updated = datetime.now()
 
 
#session.user_id = request
 #this event ensures that user_id  lastupdate is correctly stored on each 
 commit.
 event.listen(Session, before_flush, attach_user_committing)
 
 -- 
 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.
 

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



Re: [sqlalchemy] CircularDependencyError with relationships

2012-06-06 Thread Michael Bayer
you need to use the post_update option described at 
http://docs.sqlalchemy.org/en/rel_0_7/orm/relationships.html#rows-that-point-to-themselves-mutually-dependent-rows
 .

On Jun 6, 2012, at 1:15 AM, Alex Grönholm wrote:

 I have trouble configuring two relationships from one class to another. The 
 following code should be fairly self-explanatory:
 
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base
 
 
 Base = declarative_base()
 
 class Company(Base):
 __tablename__ = 'companies'
 id = Column(Integer, primary_key=True)
 default_address_id = Column(Integer, ForeignKey('addresses.id', 
 use_alter=True, name='defaultaddress_fk'))
 addresses = relationship('Address', backref='company', 
 primaryjoin='Address.company_id == Company.id')
 default_address = relationship('Address', 
 primaryjoin='Company.default_address_id == Address.id')
 
 
 class Address(Base):
 __tablename__ = 'addresses'
 id = Column(Integer, primary_key=True)
 company_id = Column(Integer, ForeignKey(Company.id), nullable=False)
 
 
 engine = create_engine('sqlite:///', echo=True)
 Base.metadata.create_all(engine)
 session = Session(engine)
 company = Company()
 address = Address()
 session.add(company)
 company.default_address = address
 company.addresses.append(address)
 session.flush()
 
 
 What I expect is SQLAlchemy to 1) create the company, 2) create the address 
 with the new company's id in company_id, 3) assign the ID of the new address 
 to company.default_address_id
 Trouble is, I get this error:
 
 sqlalchemy.exc.CircularDependencyError: Circular dependency detected. Cycles: 
 set([ProcessState(ManyToOneDP(Company.default_address), Company at 
 0x16a7210, delete=False), ProcessState(ManyToOneDP(Address.company), 
 Address at 0x16ad190, delete=False), SaveUpdateState(Company at 
 0x16a7210), ProcessState(OneToManyDP(Company.addresses), Company at 
 0x16a7210, delete=False), SaveUpdateState(Address at 0x16ad190)]) all 
 edges: set([(ProcessState(OneToManyDP(Company.addresses), Company at 
 0x16a7210, delete=False), SaveUpdateState(Address at 0x16ad190)), 
 (SaveUpdateState(Address at 0x16ad190), 
 ProcessState(ManyToOneDP(Company.default_address), Company at 0x16a7210, 
 delete=False)), (SaveUpdateState(Company at 0x16a7210), 
 SaveUpdateState(Address at 0x16ad190)), (SaveUpdateState(Company at 
 0x16a7210), ProcessState(ManyToOneDP(Address.company), Address at 
 0x16ad190, delete=False)), 
 (ProcessState(ManyToOneDP(Company.default_address), Company at 0x16a7210, 
 delete=False), SaveUpdateState(Company at 0x16a7210)), 
 (ProcessState(ManyToOneDP(Address.company), Address at 0x16ad190, 
 delete=False), SaveUpdateState(Address at 0x16ad190)), 
 (SaveUpdateState(Company at 0x16a7210), 
 ProcessState(OneToManyDP(Company.addresses), Company at 0x16a7210, 
 delete=False))])
 
 What am I doing wrong? I had a similar problem in my production app when 
 trying to delete a Company that had a default address assigned.
 I'm on SQLAlchemy 0.7.7.
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To view this discussion on the web visit 
 https://groups.google.com/d/msg/sqlalchemy/-/fqFKTLBdTYwJ.
 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.

-- 
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: 'InstanceState' object has no attribute 'manager.mapper', w/ Jython2.7.2

2012-06-06 Thread SA User
Ah, you're right, it does look like a Jython bug.

When I run the code you provided above I get the error below, which
does show that it's a Jython issue.

Traceback (most recent call last):
  File t.py, line 13, in module
print attrgetter(bar.bat)(f)
AttributeError: 'Foo' object has no attribute 'bar.bat'


I'll let the Jython folks know.

Thanks for the fast response, you saved me a lot of head-banging and
code spelunking.

-Alex

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



Re: [sqlalchemy] CircularDependencyError with relationships

2012-06-06 Thread Alex Grönholm

06.06.2012 18:06, Michael Bayer kirjoitti:
you need to use the post_update option described at 
http://docs.sqlalchemy.org/en/rel_0_7/orm/relationships.html#rows-that-point-to-themselves-mutually-dependent-rows 
.

Thanks for the pointer. Problem solved :)


On Jun 6, 2012, at 1:15 AM, Alex Grönholm wrote:

I have trouble configuring two relationships from one class to 
another. The following code should be fairly self-explanatory:



from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base


Base = declarative_base()

class Company(Base):
__tablename__ = 'companies'
id = Column(Integer, primary_key=True)
default_address_id = Column(Integer, ForeignKey('addresses.id', 
use_alter=True, name='defaultaddress_fk'))
addresses = relationship('Address', backref='company', 
primaryjoin='Address.company_id == Company.id')
default_address = relationship('Address', 
primaryjoin='Company.default_address_id == Address.id')



class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
company_id = Column(Integer, ForeignKey(Company.id), nullable=False)


engine = create_engine('sqlite:///', echo=True)
Base.metadata.create_all(engine)
session = Session(engine)
company = Company()
address = Address()
session.add(company)
company.default_address = address
company.addresses.append(address)
session.flush()


What I expect is SQLAlchemy to 1) create the company, 2) create the 
address with the new company's id in company_id, 3) assign the ID of 
the new address to company.default_address_id

Trouble is, I get this error:

sqlalchemy.exc.CircularDependencyError: Circular dependency detected. 
Cycles: set([ProcessState(ManyToOneDP(Company.default_address), 
Company at 0x16a7210, delete=False), 
ProcessState(ManyToOneDP(Address.company), Address at 0x16ad190, 
delete=False), SaveUpdateState(Company at 0x16a7210), 
ProcessState(OneToManyDP(Company.addresses), Company at 0x16a7210, 
delete=False), SaveUpdateState(Address at 0x16ad190)]) all edges: 
set([(ProcessState(OneToManyDP(Company.addresses), Company at 
0x16a7210, delete=False), SaveUpdateState(Address at 0x16ad190)), 
(SaveUpdateState(Address at 0x16ad190), 
ProcessState(ManyToOneDP(Company.default_address), Company at 
0x16a7210, delete=False)), (SaveUpdateState(Company at 0x16a7210), 
SaveUpdateState(Address at 0x16ad190)), (SaveUpdateState(Company 
at 0x16a7210), ProcessState(ManyToOneDP(Address.company), Address 
at 0x16ad190, delete=False)), 
(ProcessState(ManyToOneDP(Company.default_address), Company at 
0x16a7210, delete=False), SaveUpdateState(Company at 0x16a7210)), 
(ProcessState(ManyToOneDP(Address.company), Address at 0x16ad190, 
delete=False), SaveUpdateState(Address at 0x16ad190)), 
(SaveUpdateState(Company at 0x16a7210), 
ProcessState(OneToManyDP(Company.addresses), Company at 0x16a7210, 
delete=False))])


What am I doing wrong? I had a similar problem in my production app 
when trying to delete a Company that had a default address assigned.

I'm on SQLAlchemy 0.7.7.

--
You received this message because you are subscribed to the Google 
Groups sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/fqFKTLBdTYwJ.
To post to this group, send email to sqlalchemy@googlegroups.com 
mailto:sqlalchemy@googlegroups.com.
To unsubscribe from this group, send email to 
sqlalchemy+unsubscr...@googlegroups.com 
mailto: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 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.


--
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: before_flush event doesn't seem to permit additional update to dirty objects

2012-06-06 Thread Damian
Hello,

Thanks for the response - how do I access the public new collection?

In terms of the date not being updated - turns out that in my code the
columns are called last_update_date and not last_updated which
explains why it wasn't committing anything

Also, for the Session.dirty objects I check that they've actually been
modified before committing using is_modified -

   for obj in Session.dirty:
 log.debug('Objects in dirty: %s' % obj.__dict__)
 if Session.is_modified(obj, passive=True):
 obj.user_id = user_id
 obj.last_updated = datetime.now()


Thank you for helping me spot this,

Damian

On Jun 6, 4:06 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 The code looks fine to me, other than the access of Session._new for which 
 you should be really calling upon the public new collection.

 What you might want to make sure of is that the objects you expect to see in 
 dirty are actually there.   Sometimes objects don't make it into dirty 
 until they are found to be impacted by a relationship() changing something on 
 them.   If this is the case you'd want to navigate to those objects 
 differently.

 On Jun 6, 2012, at 6:36 AM, Damian Dimmich wrote:







  Hi,

  I have a before flush event set up that sets the current user_id and 
  datetime on new objects that are going to be commited to the database (all 
  tables have these fields).

  Unfortunately, it seems to ignore changes I make to existing objects, ie 
  when I set the user_id (which i get from pyramid) and last_updated columns 
  in the event handler, the sql only issues updates for the other columns 
  that where modified.

  Any ideas as to what am I missing?

  Thanks in advance,
  Damian

  def attach_user_committing(Session, flush_context, instances):
     This function gets called by the before_flush event,
     it grabs the current threads request and extracts the
     authenticated user_id out of it.  You can only
     commit things if you are authenticated.

     Once it has that id, it goes through and adds the id
     of the user who modified it to new commits- need to be careful that
     _new doesn't change.
     

     #this is used when creating databases  testing only
     user_id = 1
     if not creating_database:
         user_id = 
  authenticated_userid(pyramid.threadlocal.get_current_request())
     #for each object being committed/flushed, set the flushing/commiting user
     for obj in Session._new.values():
         #log.debug(obj)
         obj.user_id = user_id
         obj.last_updated = datetime.now()
     log.debug('Session dirty is : %s' %Session.dirty)
     for obj in Session.dirty:
         log.debug('Objects in dirty: %s' % obj.__dict__)
         #if obj._sa_instance_state.modified:
         obj.user_id = user_id
         obj.last_updated = datetime.now()

     #session.user_id = request
  #this event ensures that user_id  lastupdate is correctly stored on each 
  commit.
  event.listen(Session, before_flush, attach_user_committing)

  --
  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 
  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 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] mapping without key

2012-06-06 Thread Victor Olex
With the understanding that we would loose the ability to properly
track the sate of a mapped object and ability to update or insert in
ORM and likely the ability to correctly use relationships as well -
how can one accomplish a mapper, which would work on tables (views)
without any key, which uniquely identify records in it?

The rationale for this question is to be able to be able to operate on
these tables in object (ORM) context and to join them in queries with
other normally mapped classes for reading purposes only. The ideal
solution would be perhaps a different Declarative Base class using a
modified mapper.

-- 
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] Declarative Models: Can they be used with two databases and two schema names?

2012-06-06 Thread Shawn Wheatley
Hi,

I'm trying to use my declarative models to copy data from an Oracle 
database with a non-default schema name to a SQLite database (which has no 
schema name, or at least a default name that can't be changed). Copying 
from Oracle to Oracle has not been a problem for me, but Oracle to SQLite 
will not work. The problem for me is that the schema definition used for 
SQL generation is on the table. I went through a fruitless exercise of 
calling tometadata on every table in the metadata created by the 
generated declarative base class, copying into a new MetaData object. I 
then swapped the metadata on the declarative base and ran my query, with 
the intention of swapping it back after. No luck.

The purpose of my project is to surgically extract related data for a small 
subset of accounts from our production database and bring it down to a 
local SQLite database. Does anybody have experience doing this? Am I going 
about this the wrong way?

Thanks for any help,
Shawn

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/Y6z2q5U_B8gJ.
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.



Re: [sqlalchemy] mapping without key

2012-06-06 Thread Michael Bayer
There's two variants to this question, and I can't tell which one you're asking 
for.   

If the views in question do in fact have candidate keys, that is, columns which 
uniquely identify a row, you just specify those either to the Table or mapper() 
as the columns that uniquely identify the row.   They don't have to be 
considered primary by the database in any formal way.

If OTOH you have views which truly have duplicate rows and no candidate key of 
any kind, the ORM won't do that.   As you probably know, the primary key thing 
is more or less the spine of mapper() and Query, and there's really no way the 
ORM could be refactored, without a great loss of stability and performance, to 
make this requirement optional.

If you're looking for duplicate rows to come back as individual objects, 
Query() can be handed Table objects to load rows from, so a custom Query 
subclass that wraps named tuples into objects could possibly approximate this 
effect.


On Jun 6, 2012, at 3:01 PM, Victor Olex wrote:

 With the understanding that we would loose the ability to properly
 track the sate of a mapped object and ability to update or insert in
 ORM and likely the ability to correctly use relationships as well -
 how can one accomplish a mapper, which would work on tables (views)
 without any key, which uniquely identify records in it?
 
 The rationale for this question is to be able to be able to operate on
 these tables in object (ORM) context and to join them in queries with
 other normally mapped classes for reading purposes only. The ideal
 solution would be perhaps a different Declarative Base class using a
 modified mapper.
 
 -- 
 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.
 

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



Re: [sqlalchemy] Declarative Models: Can they be used with two databases and two schema names?

2012-06-06 Thread Michael Bayer
By far the easiest approach is to modify the username you're coming into Oracle 
as so that the schema in question is the default.  Or if you can, create Oracle 
synonyms (i.e. CREATE SYNONYM) in the default schema that link to the 
schema-qualified tables.

Otherwise SQLA doesn't have a lot of ability to change the schema name.  The 
tometadata() approach you've used is the best it has, however you'd need to 
declare all new classes against those Table objects.   A recipe for doing this 
is here: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityName.

Another way you might do it is to put an event handler that modifies all the 
SQL to replace a particular schema name with something else, or nothing, like 
s/someschema./someotherschema./ type of thing. You can do this with the 
before_execute or before_cursor_execute events:

engine = create_engine(...)

@event.listens_for(engine, before_cursor_execute, retval=True)
def replace_schema(conn, cursor, statement, 
parameters, context, executemany):
statement = statement.sub(someschema., )
return statement, parameters




On Jun 6, 2012, at 3:51 PM, Shawn Wheatley wrote:

 Hi,
 
 I'm trying to use my declarative models to copy data from an Oracle database 
 with a non-default schema name to a SQLite database (which has no schema 
 name, or at least a default name that can't be changed). Copying from Oracle 
 to Oracle has not been a problem for me, but Oracle to SQLite will not work. 
 The problem for me is that the schema definition used for SQL generation is 
 on the table. I went through a fruitless exercise of calling tometadata on 
 every table in the metadata created by the generated declarative base class, 
 copying into a new MetaData object. I then swapped the metadata on the 
 declarative base and ran my query, with the intention of swapping it back 
 after. No luck.
 
 The purpose of my project is to surgically extract related data for a small 
 subset of accounts from our production database and bring it down to a local 
 SQLite database. Does anybody have experience doing this? Am I going about 
 this the wrong way?
 
 Thanks for any help,
 Shawn
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To view this discussion on the web visit 
 https://groups.google.com/d/msg/sqlalchemy/-/Y6z2q5U_B8gJ.
 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.

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



Re: [sqlalchemy] Re: before_flush event doesn't seem to permit additional update to dirty objects

2012-06-06 Thread Michael Bayer

On Jun 6, 2012, at 1:48 PM, Damian wrote:

 Hello,
 
 Thanks for the response - how do I access the public new collection?

it's called session.new




 
 In terms of the date not being updated - turns out that in my code the
 columns are called last_update_date and not last_updated which
 explains why it wasn't committing anything
 
 Also, for the Session.dirty objects I check that they've actually been
 modified before committing using is_modified -
 
   for obj in Session.dirty:
 log.debug('Objects in dirty: %s' % obj.__dict__)
 if Session.is_modified(obj, passive=True):
 obj.user_id = user_id
 obj.last_updated = datetime.now()
 
 
 Thank you for helping me spot this,
 
 Damian
 
 On Jun 6, 4:06 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 The code looks fine to me, other than the access of Session._new for which 
 you should be really calling upon the public new collection.
 
 What you might want to make sure of is that the objects you expect to see in 
 dirty are actually there.   Sometimes objects don't make it into dirty 
 until they are found to be impacted by a relationship() changing something 
 on them.   If this is the case you'd want to navigate to those objects 
 differently.
 
 On Jun 6, 2012, at 6:36 AM, Damian Dimmich wrote:
 
 
 
 
 
 
 
 Hi,
 
 I have a before flush event set up that sets the current user_id and 
 datetime on new objects that are going to be commited to the database (all 
 tables have these fields).
 
 Unfortunately, it seems to ignore changes I make to existing objects, ie 
 when I set the user_id (which i get from pyramid) and last_updated columns 
 in the event handler, the sql only issues updates for the other columns 
 that where modified.
 
 Any ideas as to what am I missing?
 
 Thanks in advance,
 Damian
 
 def attach_user_committing(Session, flush_context, instances):
This function gets called by the before_flush event,
it grabs the current threads request and extracts the
authenticated user_id out of it.  You can only
commit things if you are authenticated.
 
Once it has that id, it goes through and adds the id
of the user who modified it to new commits- need to be careful that
_new doesn't change.

 
#this is used when creating databases  testing only
user_id = 1
if not creating_database:
user_id = 
 authenticated_userid(pyramid.threadlocal.get_current_request())
#for each object being committed/flushed, set the flushing/commiting user
for obj in Session._new.values():
#log.debug(obj)
obj.user_id = user_id
obj.last_updated = datetime.now()
log.debug('Session dirty is : %s' %Session.dirty)
for obj in Session.dirty:
log.debug('Objects in dirty: %s' % obj.__dict__)
#if obj._sa_instance_state.modified:
obj.user_id = user_id
obj.last_updated = datetime.now()
 
#session.user_id = request
 #this event ensures that user_id  lastupdate is correctly stored on each 
 commit.
 event.listen(Session, before_flush, attach_user_committing)
 
 --
 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 
 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 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.
 

-- 
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: mapping without key

2012-06-06 Thread Victor Olex
Thanks. Model that we work with has tables, which have no unique
constraints. Keys can be inferred from data contained specified in ORM
maping but there is no guarantee that this will always work because
data may change. Still one could argue a case where mapping such table
to a class has merit even if far removed from all the benefits of
SQLAlchemy ORM.

On Jun 6, 4:55 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 There's two variants to this question, and I can't tell which one you're 
 asking for.

 If the views in question do in fact have candidate keys, that is, columns 
 which uniquely identify a row, you just specify those either to the Table or 
 mapper() as the columns that uniquely identify the row.   They don't have to 
 be considered primary by the database in any formal way.

 If OTOH you have views which truly have duplicate rows and no candidate key 
 of any kind, the ORM won't do that.   As you probably know, the primary key 
 thing is more or less the spine of mapper() and Query, and there's really no 
 way the ORM could be refactored, without a great loss of stability and 
 performance, to make this requirement optional.

 If you're looking for duplicate rows to come back as individual objects, 
 Query() can be handed Table objects to load rows from, so a custom Query 
 subclass that wraps named tuples into objects could possibly approximate this 
 effect.

 On Jun 6, 2012, at 3:01 PM, Victor Olex wrote:







  With the understanding that we would loose the ability to properly
  track the sate of a mapped object and ability to update or insert in
  ORM and likely the ability to correctly use relationships as well -
  how can one accomplish a mapper, which would work on tables (views)
  without any key, which uniquely identify records in it?

  The rationale for this question is to be able to be able to operate on
  these tables in object (ORM) context and to join them in queries with
  other normally mapped classes for reading purposes only. The ideal
  solution would be perhaps a different Declarative Base class using a
  modified mapper.

  --
  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 
  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 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: mapping without key

2012-06-06 Thread Victor Olex
To be clear this is not a feature request. I could use a hit how to
build a fake mapper like this if not compatible in certain cases.

On Jun 6, 5:52 pm, Victor Olex victor.o...@vtenterprise.com wrote:
 Thanks. Model that we work with has tables, which have no unique
 constraints. Keys can be inferred from data contained specified in ORM
 maping but there is no guarantee that this will always work because
 data may change. Still one could argue a case where mapping such table
 to a class has merit even if far removed from all the benefits of
 SQLAlchemy ORM.

 On Jun 6, 4:55 pm, Michael Bayer mike...@zzzcomputing.com wrote:







  There's two variants to this question, and I can't tell which one you're 
  asking for.

  If the views in question do in fact have candidate keys, that is, columns 
  which uniquely identify a row, you just specify those either to the Table 
  or mapper() as the columns that uniquely identify the row.   They don't 
  have to be considered primary by the database in any formal way.

  If OTOH you have views which truly have duplicate rows and no candidate key 
  of any kind, the ORM won't do that.   As you probably know, the primary key 
  thing is more or less the spine of mapper() and Query, and there's really 
  no way the ORM could be refactored, without a great loss of stability and 
  performance, to make this requirement optional.

  If you're looking for duplicate rows to come back as individual objects, 
  Query() can be handed Table objects to load rows from, so a custom Query 
  subclass that wraps named tuples into objects could possibly approximate 
  this effect.

  On Jun 6, 2012, at 3:01 PM, Victor Olex wrote:

   With the understanding that we would loose the ability to properly
   track the sate of a mapped object and ability to update or insert in
   ORM and likely the ability to correctly use relationships as well -
   how can one accomplish a mapper, which would work on tables (views)
   without any key, which uniquely identify records in it?

   The rationale for this question is to be able to be able to operate on
   these tables in object (ORM) context and to join them in queries with
   other normally mapped classes for reading purposes only. The ideal
   solution would be perhaps a different Declarative Base class using a
   modified mapper.

   --
   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 
   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 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] auto reflect to create table declarative table code

2012-06-06 Thread Benjamin Hitz
This seems (to me) like an obvious question but a brief googling and looking at 
the docs didn't seem to find the answer.

I have an existing database (lets say mysql)
I can easily create object like:

class BroadPeaks(Base):
__table__ = Table('broad_peaks', Base.metadata, autoload=True)

def __repr__(self):
return 'Peak %r' % (self.peak_name)

Once I am connected, yay.  And I think this has already all the relationships I 
need.

But let's say I am S lazy that I just want to auto generate the lines:

class ClassName(Base)
__table__ = Table('table_name', Base.metadata, autoload=True)

For each table.  Should I just introspect the metadata object?  I thought of 
this but not all the tables were loaded...

Ben
--
Ben Hitz
Senior Scientific Programmer ** Saccharomyces Genome Database ** GO Consortium
Stanford University ** h...@stanford.edu



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



Re: [sqlalchemy] auto reflect to create table declarative table code

2012-06-06 Thread Michael Bayer

On Jun 6, 2012, at 7:47 PM, Benjamin Hitz wrote:

 This seems (to me) like an obvious question but a brief googling and looking 
 at the docs didn't seem to find the answer.
 
 I have an existing database (lets say mysql)
 I can easily create object like:
 
 class BroadPeaks(Base):
__table__ = Table('broad_peaks', Base.metadata, autoload=True)
 
def __repr__(self):
return 'Peak %r' % (self.peak_name)
 
 Once I am connected, yay.  And I think this has already all the relationships 
 I need.
 
 But let's say I am S lazy that I just want to auto generate the lines:
 
 class ClassName(Base)
__table__ = Table('table_name', Base.metadata, autoload=True)
 
 For each table.  Should I just introspect the metadata object?  I thought of 
 this but not all the tables were loaded...

if you're incredibly lazy to that degree you might want to check out / help out 
with SQLSoup, which has been with SQLAlchemy since the beginning but is now 
it's own project:

http://readthedocs.org/docs/sqlsoup/en/latest/tutorial.html

basically you give it a name, it reflects that name and maps it.   All kinds of 
caveats apply.

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



Re: [sqlalchemy] auto reflect to create table declarative table code

2012-06-06 Thread Benjamin Hitz

Nah, I don't want a simpler interface, I want something that just generates the 
code so I can extend it as needed.

Ben
On Jun 6, 2012, at 5:57 PM, Michael Bayer wrote:

 
 On Jun 6, 2012, at 7:47 PM, Benjamin Hitz wrote:
 
 This seems (to me) like an obvious question but a brief googling and looking 
 at the docs didn't seem to find the answer.
 
 I have an existing database (lets say mysql)
 I can easily create object like:
 
 class BroadPeaks(Base):
   __table__ = Table('broad_peaks', Base.metadata, autoload=True)
 
   def __repr__(self):
   return 'Peak %r' % (self.peak_name)
 
 Once I am connected, yay.  And I think this has already all the 
 relationships I need.
 
 But let's say I am S lazy that I just want to auto generate the lines:
 
 class ClassName(Base)
   __table__ = Table('table_name', Base.metadata, autoload=True)
 
 For each table.  Should I just introspect the metadata object?  I thought of 
 this but not all the tables were loaded...
 
 if you're incredibly lazy to that degree you might want to check out / help 
 out with SQLSoup, which has been with SQLAlchemy since the beginning but is 
 now it's own project:
 
 http://readthedocs.org/docs/sqlsoup/en/latest/tutorial.html
 
 basically you give it a name, it reflects that name and maps it.   All kinds 
 of caveats apply.
 
 -- 
 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.
 

--
Ben Hitz
Senior Scientific Programmer ** Saccharomyces Genome Database ** GO Consortium
Stanford University ** h...@stanford.edu



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