Re: [sqlalchemy] avoid setting attribute on init and or.reconstructor

2020-11-17 Thread lars van gemerden
Thanks Mike, I oversimplified a little bit (the factory function takes more 
arguments than self.stops, not part of the Planning class), but if i create 
the factory with partial I think it will work. 

On Monday, November 16, 2020 at 6:16:24 PM UTC+1 Mike Bayer wrote:

> I would use a memoized descriptor for that and have it evaluate when 
> called.
>
> Amazingly, i can't find public examples of Python memoize decorators that 
> aren't overwrought.we use one that is completely efficient and simple:
>
> class memoized_property(object):
> """A read-only @property that is only evaluated once."""
>
> def __init__(self, fget, doc=None):
> self.fget = fget
> self.__doc__ = doc or fget.__doc__
> self.__name__ = fget.__name__
>
> def __get__(self, obj, cls):
> if obj is None:
> return self
> obj.__dict__[self.__name__] = result = self.fget(obj)
> return result
>
>
> then you can just set it up as:
>
> class Planning(...):
> @memoized_property
> def matrix(self):
> return self.matrix_factor(self.stops)
>
>
>
>
> On Mon, Nov 16, 2020, at 11:43 AM, lars van gemerden wrote:
>
> Hi Mike,
>
> What if during reconstruction you need a one-to-many attribute, like:
>
> class Planning(SqlaBase):
> stops = relationship(*"Stop"*, back_populates=*"planning"*, lazy=
> *"joined"*)
>
> matrix_factory = Matrix
>
> def __init__(self, **kwargs):
> super().__init__(**kwargs)
> self.matrix = self.matrix_factory(self.stops)
>
> @reconstructor
> def init_on_load(self):
>  self.matrix = self.matrix_factory(self.stops)
> The docs say self.stops will not be completely loaded in init_on_load, how 
> could i make this work?
>
> Cheers, Lars
> On Monday, August 7, 2017 at 6:09:08 AM UTC+2 Mike Bayer wrote:
>
>
>
> On Aug 6, 2017 1:33 PM, "Shane Carey"  wrote:
>
> Hey Mike,
>
> I can expand my example. I have an orm mapped attribute like this
>
> class Obj(Base):
> _evaluator = Column(String)
>
> def __init__(self, **kwargs):
> super().__init__(**kwargs)
> self._eval_func = eval(self._evaluator)
>
> @orm.reconstructor
> def init_on_load(self):
> self._eval_func = eval(self._evaluator)
>
> @property
> def evaluator(self):
>  return self._eval_func
>
> @evaluator.setter
> def set_evaluator(ev):
> self._evaluator = ev
> self._eval_func = eval(self._evaluator)
>
> You can see that I have to explicitly set self._eval_func in three 
> different places, when really I just want to set it every time 
> self._evaluator is set.
>
> It looks to me like the orm events are just a different way of placing the 
> different settings of this class attribute
>
> Also, I would like to not call eval in the getter of the property for the 
> sake of performance (I know that would simplify the issue).
>
> Is there a way to intercept the setting of self._evaluator for all cases?
>
>
>
> Use the init and load event listeners from my previous email on top of one 
> function.  It will be called for init and load. 
>
>
>
> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+...@googlegroups.com.
> To post to this group, send email to sqlal...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
>
> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+...@googlegroups.com.
>
> To view this discussion on the web visit 
> https://groups.google.com/d/msgid/sqlalchemy/e9b2b9ff-0979-43be-94f4-fdb3ceb48ae9n%40googlegroups.com
>  
>

Re: [sqlalchemy] avoid setting attribute on init and or.reconstructor

2020-11-16 Thread lars van gemerden
Hi Mike,

What if during reconstruction you need a one-to-many attribute, like:

class Planning(SqlaBase):
stops = relationship("Stop", back_populates="planning", lazy="joined")

matrix_factory = Matrix

def __init__(self, **kwargs):
super().__init__(**kwargs)
self.matrix = self.matrix_factory(self.stops)

@reconstructor
def init_on_load(self):
 self.matrix = self.matrix_factory(self.stops)

The docs say self.stops will not be completely loaded in init_on_load, how 
could i make this work?

Cheers, Lars
On Monday, August 7, 2017 at 6:09:08 AM UTC+2 Mike Bayer wrote:

>
>
> On Aug 6, 2017 1:33 PM, "Shane Carey"  wrote:
>
> Hey Mike,
>
> I can expand my example. I have an orm mapped attribute like this
>
> class Obj(Base):
> _evaluator = Column(String)
>
> def __init__(self, **kwargs):
> super().__init__(**kwargs)
> self._eval_func = eval(self._evaluator)
>
> @orm.reconstructor
> def init_on_load(self):
> self._eval_func = eval(self._evaluator)
>
> @property
> def evaluator(self):
>  return self._eval_func
>
> @evaluator.setter
> def set_evaluator(ev):
> self._evaluator = ev
> self._eval_func = eval(self._evaluator)
>
> You can see that I have to explicitly set self._eval_func in three 
> different places, when really I just want to set it every time 
> self._evaluator is set.
>
> It looks to me like the orm events are just a different way of placing the 
> different settings of this class attribute
>
> Also, I would like to not call eval in the getter of the property for the 
> sake of performance (I know that would simplify the issue).
>
> Is there a way to intercept the setting of self._evaluator for all cases?
>
>
>
> Use the init and load event listeners from my previous email on top of one 
> function.  It will be called for init and load. 
>
>
> -- 
> SQLAlchemy - 
> The Python SQL Toolkit and Object Relational Mapper
>  
> http://www.sqlalchemy.org/
>  
> To post example code, please provide an MCVE: Minimal, Complete, and 
> Verifiable Example. See http://stackoverflow.com/help/mcve for a full 
> description.
> --- 
> You received this message because you are subscribed to the Google Groups 
> "sqlalchemy" group.
> To unsubscribe from this group and stop receiving emails from it, send an 
> email to sqlalchemy+unsubscr...@googlegroups.com.
> To post to this group, send email to sqlal...@googlegroups.com.
> Visit this group at https://groups.google.com/group/sqlalchemy.
> For more options, visit https://groups.google.com/d/optout.
>
>
>

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sqlalchemy/e9b2b9ff-0979-43be-94f4-fdb3ceb48ae9n%40googlegroups.com.


Re: [sqlalchemy] Possible Exceptions

2017-11-30 Thread Lars Liedtke (SCC)


Am 29.11.2017 um 17:16 schrieb Mike Bayer:
> On Wed, Nov 29, 2017 at 11:12 AM, Mike Bayer <mike...@zzzcomputing.com> wrote:
>> On Wed, Nov 29, 2017 at 3:37 AM,  <lars.lied...@kit.edu> wrote:
>>> Hello everybody,
>>>
>>> I am writing some piece of code, which should not exit unforseen in the best
>>> case, at least it should write to a log file what went wrong (e.g. Database
>>> not reachable, etc). So I tried figuring out, which Exceptions would be
>>> possibly thrown by SQLAlchemy:
> let me also add that if "unforseen exit" is the issue, you're mostly
> going to look for the SQL-related errors thrown by the driver which on
> the SQLAlchemy side are the DBAPIError classes, however even in that
> case, some of those errors mean "couldn't connect to the database",
> which could be mis-configuration OR the database is down, others can
> mean "SQL is wrong".   So even then it's hard to know ahead of time
> what conditions can be caught and handled vs. which ones mean the
> program needs to be re-configured and restarted.
Of course, In my case it will be a call from the crontab starting my
process regularly, I just wanted my process not to exit without writing
it to the logfile what the problem was with a "nicely" formatted
message, so the logfiles can be checked for certain messages in ELK. So
I think I can limit them down to if there is an error connecting to the
database because the queries are pretty much fixed and only differ in
which element(s) I query and of course I have to make sure that the
configuration is correct.
>
>
>
>
>> the exception classes are documented at:
>>
>> http://docs.sqlalchemy.org/en/latest/core/exceptions.html
>> http://docs.sqlalchemy.org/en/latest/orm/exceptions.html
>>
>> i will note that while the ORM exceptions are linked from the front
>> page of the docs, the Core ones are not, you need to go into the full
>> table of contents to see it
>> (http://docs.sqlalchemy.org/en/latest/contents.html).
>>
>> as to the exact codepath that can raise these, it depends on the
>> exception.   The docstrings for the exceptions themselves can of
>> course have some additional detail as to what kinds of operations
>> might raise them.Though generic ones like "InvalidRequestError" or
>> "ArgumentError" are thrown in dozens of places wherever the library is
>> asked to do something that doesn't make sense or function arguments
>> that don't make sense are detected.
Thank you very much, I must have not seen the Link.
>>
>>> The first thing I did was googling for how to find out which Exceptions
>>> could be thrown in Python. The answers I found on Stack Overflow etc. were
>>> like "You simply don't", "This is Python, dumbass, you can't predict which
>>> are thrown so don't even try" or "Just write tests until you found them all"
>>> and "Just catch the general Exception class."
>>> So I tried looking at the SQLAlchemy Documentation to see if there is
>>> something written about when something goes wrong, but still no luck.
>>> Before I started digging into the code I thought I'd ask here first
>>>
>>> So is there any hint to know which Exceptions could be thrown by SQLAlchemy?
>>> The error cases I could think of were mostly wrrors while connecting to the
>>> database or having errors in queries. I would totally be willing to help
>>> with documenting at a certain point but even for this I need to know if I
>>> just did't find any documentation for this and if you consider this as
>>> neccessary. I feel that it is neccessary for me not just to kill the process
>>> with maybe a stack trace on stdout.
>>>
>>>
>>> Cheers
>>>
>>> Lars Liedtke
>>>
>>> --
>>> SQLAlchemy -
>>> The Python SQL Toolkit and Object Relational Mapper
>>>
>>> http://www.sqlalchemy.org/
>>>
>>> To post example code, please provide an MCVE: Minimal, Complete, and
>>> Verifiable Example. See http://stackoverflow.com/help/mcve for a full
>>> description.
>>> ---
>>> You received this message because you are subscribed to the Google Groups
>>> "sqlalchemy" group.
>>> To unsubscribe from this group and stop receiving emails from it, send an
>>> email to sqlalchemy+unsubscr...@googlegroups.com.
>>> To post to this group, send email to sqlalchemy@googlegroups.com.
>>> Visit this group at https://groups.google.com/group/sqlalchemy.
>>> For more options, vis

[sqlalchemy] Possible Exceptions

2017-11-29 Thread lars . liedtke
Hello everybody,

I am writing some piece of code, which should not exit unforseen in the 
best case, at least it should write to a log file what went wrong (e.g. 
Database not reachable, etc). So I tried figuring out, which Exceptions 
would be possibly thrown by SQLAlchemy:

   - The first thing I did was googling for how to find out which 
   Exceptions could be thrown in Python. The answers I found on Stack Overflow 
   etc. were like "You simply don't", "This is Python, dumbass, you can't 
   predict which are thrown so don't even try" or "Just write tests until you 
   found them all" and "Just catch the general Exception class."
   - So I tried looking at the SQLAlchemy Documentation to see if there is 
   something written about when something goes wrong, but still no luck.
   - Before I started digging into the code I thought I'd ask here first

So is there any hint to know which Exceptions could be thrown by 
SQLAlchemy? The error cases I could think of were mostly wrrors while 
connecting to the database or having errors in queries. I would totally be 
willing to help with documenting at a certain point but even for this I 
need to know if I just did't find any documentation for this and if you 
consider this as neccessary. I feel that it is neccessary for me not just 
to kill the process with maybe a stack trace on stdout.


Cheers

Lars Liedtke

-- 
SQLAlchemy - 
The Python SQL Toolkit and Object Relational Mapper

http://www.sqlalchemy.org/

To post example code, please provide an MCVE: Minimal, Complete, and Verifiable 
Example.  See  http://stackoverflow.com/help/mcve for a full description.
--- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] join aliased

2014-03-25 Thread lars van gemerden
OK, thank you

On Saturday, March 22, 2014 9:03:01 PM UTC+1, Michael Bayer wrote:


 On Mar 22, 2014, at 9:16 AM, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote: 

  query = session.query(Email) 
  query = query.join(user) #or query = query.join(user, 
 aliased = True) 
  query = query.add_columns(Email.email, User.name) 

 the add_columns() method does not have the clause adaptation behavior of 
 filter(), so it does not take into account the fact that “aliased=True” was 
 called when the User entity was first pulled in.  so this pulls in the User 
 entity twice, once from User.name, and another because of the aliased(User) 
 brought in by the join. 

 solution is not to use aliased=True (a feature I would never have added if 
 it were today), use  ua = aliased(User); q.join(ua, “user”); 
 query.add_columns(ua.name). 





-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] a relationship question

2014-03-25 Thread lars van gemerden
Hi all,

Simple question, but couldn't find it in the docs:

- How can i retrieve the target class in a relationship in the ORM? Say i 
have a sqla class with a relationship(User, primaryjoin = ...), how can i 
retrieve the User class from the relationship ('relationship' is a 
descriptor, right?)


Cheers, Lars  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] join aliased

2014-03-22 Thread lars van gemerden
Hi all,

Maybe (hopefully;-) i am missing something simple, but i have the following 
test code:

engine = create_engine('sqlite:///:memory:', echo=True) 
Session = sessionmaker(bind=engine)   
Base = declarative_base()

class User(Base):
__tablename__ = 'user_table'
id = Column(Integer, primary_key=True)
name = Column(String)

addresses = relationship(Email, back_populates=user)

class Email(Base):
__tablename__ = 'email_table'
id = Column(Integer, primary_key=True)
email = Column(String)
user_id = Column(Integer, ForeignKey('user_table.id'))

user = relationship(User, back_populates=addresses)

Base.metadata.create_all(engine) 

u1 = User(name = bob)
u2 = User(name = jan)
a1 = Email(email = b...@school.nl, user = u1)
a2 = Email(email = j...@school.nl, user = u2)
a3 = Email(email = j...@home.nl, user = u2)

session = Session()
session.add_all([u1, u2, a1, a2, a3])
session.commit()
query = session.query(Email)
query = query.join(user) #or query = query.join(user, aliased = 
True)
query = query.add_columns(Email.email, User.name)
for r in query.all():
print r[1:],
print

and if i use the line:

query = query.join(user)

this results in:

  (u'b...@school.nl', u'bob') (u'j...@school.nl', u'jan') 
(u'j...@home.nl', u'jan')

which i would expect, but if i exchange the line with:

 query = query.join(user, aliased = True)

i get the full cross product between the tables:

 (u'b...@school.nl', u'bob') (u'j...@school.nl', u'bob') (u'j...@home.nl', 
u'bob') (u'b...@school.nl', u'jan') (u'j...@school.nl', u'jan') 
(u'j...@home.nl', u'jan')

Can anyone explain why this difference occurs?

Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Re: label column_descriptions

2014-03-20 Thread lars van gemerden
I solved it (again):

for future reference:

say you have the expression Person.name (Person is SQLA class) to use in a 
query, to have a label show up under that name in the resulting 
KeyedTuple's:

to do:

Person.name.label(something) 

is not enough, you have to do:

expr = Person.name.label(something) 

and something like query.add_column(expr) after.

Also Person.name.label(Person.name) and 
 Person.name.label(Person_name)give exceptions!

(I am auto generating labels to use as column names on gui tables in a web 
page and guess which 2 i tried first :-)

Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] Re: label column_descriptions

2014-03-20 Thread lars van gemerden
thanks, Michael,

we crossed responses; i thought it was something like that, but there are 
some gotchas (at least for me; see above).

CL

On Thursday, March 20, 2014 2:22:24 PM UTC+1, lars van gemerden wrote:

 I solved it (again):

 for future reference:

 say you have the expression Person.name (Person is SQLA class) to use in a 
 query, to have a label show up under that name in the resulting 
 KeyedTuple's:

 to do:

 Person.name.label(something) 

 is not enough, you have to do:

 expr = Person.name.label(something) 

 and something like query.add_column(expr) after.

 Also Person.name.label(Person.name) and 
  Person.name.label(Person_name)give exceptions!

 (I am auto generating labels to use as column names on gui tables in a web 
 page and guess which 2 i tried first :-)

 Cheers, Lars


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] label column_descriptions

2014-03-20 Thread lars van Gemerden
 Hi Michael,

OK, that's why.

Below are the stack traces. They are not the same for A.b and A_b. If i use
other labels this error does not happen.

cheers, lars

with expr.label( %s_%s % (cls.__name__, attr_name)):

File C:\python27\lib\site-packages\bottle.py, line 781, in _handle
return route.call(**args)
  File C:\python27\lib\site-packages\bottle.py, line 1592, in wrapper
rv = callback(*a, **ka)
  File D:\Documents\Code\python\floware\server\webserver.py, line 174, in
trigger
return manager.get_gui(session).get_json(session)
  File D:\Documents\Code\python\floware\models\role\roles.py, line 275,
in get_json
activities:[a.get_json(websession) for a in self.itermodel()]}
  File D:\Documents\Code\python\floware\models\role\roles.py, line 317,
in get_json
json = self.process.get_json(websession)
  File D:\Documents\Code\python\floware\models\flow\libraries\json.py,
line 41, in get_json
peeks: [task.peek() for task in tasks]}
  File D:\Documents\Code\python\floware\models\flow\tasks.py, line 127,
in peek
content = peek(self)[0:60]
  File D:\Documents\Code\python\floware\models\flow\tasks.py, line 26, in
peek
return  | .join([peek(v) for v in value.itervalues()])
  File D:\Documents\Code\python\floware\models\flow\tasks.py, line 21, in
peek
return value._peek_()
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 46, in _peek_
return  | .join(obj[0]._peek_() for obj in self)
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 46, in genexpr
return  | .join(obj[0]._peek_() for obj in self)
  File C:\python27\lib\_abcoll.py, line 581, in __iter__
v = self[i]
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 65, in __getitem__
return self._results_()[index]
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 41, in _results_
self.refresh()
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 51, in refresh
self.__results = self.all()
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 70, in all
return self._query_.with_session(session).all()
  File build\bdist.win32\egg\sqlalchemy\orm\query.py, line 2241, in all
return list(self)
  File build\bdist.win32\egg\sqlalchemy\orm\loading.py, line 75, in
instances
labels) for row in fetch]
  File build\bdist.win32\egg\sqlalchemy\orm\loading.py, line 447, in
_instance
populate_state(state, dict_, row, isnew, only_load_props)
  File build\bdist.win32\egg\sqlalchemy\orm\loading.py, line 301, in
populate_state
populator(state, dict_, row)
  File build\bdist.win32\egg\sqlalchemy\orm\strategies.py, line 151, in
fetch_col
dict_[key] = row[col]
InvalidRequestError: Ambiguous column name 'Toetsing.cijfer' in result set!
try 'use_labels' option on select statement.


with expr.label(%s.%s % (cls.__name__, attr_name)):

Traceback (most recent call last):
  File C:\python27\lib\site-packages\bottle.py, line 781, in _handle
return route.call(**args)
  File C:\python27\lib\site-packages\bottle.py, line 1592, in wrapper
rv = callback(*a, **ka)
  File D:\Documents\Code\python\floware\server\webserver.py, line 174, in
trigger
return manager.get_gui(session).get_json(session)
  File D:\Documents\Code\python\floware\models\role\roles.py, line 275,
in get_json
activities:[a.get_json(websession) for a in self.itermodel()]}
  File D:\Documents\Code\python\floware\models\role\roles.py, line 317,
in get_json
json = self.process.get_json(websession)
  File D:\Documents\Code\python\floware\models\flow\libraries\json.py,
line 41, in get_json
peeks: [task.peek() for task in tasks]}
  File D:\Documents\Code\python\floware\models\flow\tasks.py, line 127,
in peek
content = peek(self)[0:60]
  File D:\Documents\Code\python\floware\models\flow\tasks.py, line 26, in
peek
return  | .join([peek(v) for v in value.itervalues()])
  File D:\Documents\Code\python\floware\models\flow\tasks.py, line 21, in
peek
return value._peek_()
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 46, in _peek_
return  | .join(obj[0]._peek_() for obj in self)
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 46, in genexpr
return  | .join(obj[0]._peek_() for obj in self)
  File C:\python27\lib\_abcoll.py, line 581, in __iter__
v = self[i]
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 65, in __getitem__
return self._results_()[index]
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 41, in _results_
self.refresh()
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 51, in refresh
self.__results = self.all()
  File D:\Documents\Code\python\floware\models\flow\libraries\queries.py,
line 70, in all
return self._query_.with_session(session).all()
  File build\bdist.win32\egg

Re: [sqlalchemy] AssertionError

2014-03-19 Thread lars van gemerden
clear and bug found .. thanks



On Tuesday, March 18, 2014 4:51:36 PM UTC+1, Michael Bayer wrote:

 it means this:

 a1 = A(id=1)
 session.add(a1)
 session.commit()

 a2 = A(id=1)
 session.add(a2)   # — error


 On Mar 18, 2014, at 9:59 AM, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote:

 Hi all,

 Does anyone know hoe to interpret the following error?

 AssertionError: A conflicting state is already present in the identity 
 map for key (class 'models.data.database.Keuze', (1,))

 Cheers, Lars

 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+...@googlegroups.com javascript:.
 To post to this group, send email to sqlal...@googlegroups.comjavascript:
 .
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/d/optout.




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


[sqlalchemy] AssertionError

2014-03-18 Thread lars van gemerden
Hi all,

Does anyone know hoe to interpret the following error?

AssertionError: A conflicting state is already present in the identity 
map for key (class 'models.data.database.Keuze', (1,))

Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.


Re: [sqlalchemy] StaleDataError/ObjectDeletedError

2014-02-01 Thread lars van gemerden
Thanks, this helps some to narrow it down.

Trying to zoom in:

- why would sqla try to UPDATE (instead of INSERT) a row in the database, 
when the row/object was never committed before?
- when you flush an object to the database and then close the session that 
flushed (no commit), what happens to the flushed data?
- if an object is in a session and it has_identity, why would accessing 
obj.id (id is the primary key) fail (see above)? 
- Is there (in principle) a problem with:
 + having an object of a mapped class which was never committed 
(but maybe was added to a session and flushed, after which the session was 
closed)
 + setting an attribute of that object with another object that was 
queried from the database
 + committing the first object to the database?

Cheers, Lars

On Saturday, February 1, 2014 3:42:09 AM UTC+1, Michael Bayer wrote:


 On Jan 31, 2014, at 8:11 PM, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote:


 this means an object was meant to be UPDATEed via the ORM, however the 
 row which is the target of the UPDATE is missing.  Either the primary key 
 of this row changed somehow, or the row was deleted, *or* the row is not 
 visible to your transaction (this seems to be your case).

 -  could the error also occur when the object was never committed to the 
 database (which seems to be the case; the commit where the error occurs 
 should be the first time the Company object is committed to the database)?


 sure

 -  this seems to suggest that it is possible that a row is in the 
 database, but that it is not visible to a transaction; is that possible?


 absolutely, the link http://en.wikipedia.org/wiki/Transaction_isolation is 
 relevant here




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] StaleDataError/ObjectDeletedError

2014-02-01 Thread lars van gemerden
Oh, on more question:

might there be anything inherently wrong with the scoped_session approach 
that i showed in the code snippets above?

CL

On Saturday, February 1, 2014 1:25:27 PM UTC+1, lars van gemerden wrote:

 Thanks, this helps some to narrow it down.

 Trying to zoom in:

 - why would sqla try to UPDATE (instead of INSERT) a row in the database, 
 when the row/object was never committed before?
 - when you flush an object to the database and then close the session that 
 flushed (no commit), what happens to the flushed data?
 - if an object is in a session and it has_identity, why would accessing 
 obj.id (id is the primary key) fail (see above)? 
 - Is there (in principle) a problem with:
  + having an object of a mapped class which was never committed 
 (but maybe was added to a session and flushed, after which the session was 
 closed)
  + setting an attribute of that object with another object that 
 was queried from the database
  + committing the first object to the database?

 Cheers, Lars

 On Saturday, February 1, 2014 3:42:09 AM UTC+1, Michael Bayer wrote:


 On Jan 31, 2014, at 8:11 PM, lars van gemerden la...@rational-it.com 
 wrote:


 this means an object was meant to be UPDATEed via the ORM, however the 
 row which is the target of the UPDATE is missing.  Either the primary key 
 of this row changed somehow, or the row was deleted, *or* the row is not 
 visible to your transaction (this seems to be your case).

 -  could the error also occur when the object was never committed to the 
 database (which seems to be the case; the commit where the error occurs 
 should be the first time the Company object is committed to the database)?


 sure

 -  this seems to suggest that it is possible that a row is in the 
 database, but that it is not visible to a transaction; is that possible?


 absolutely, the link http://en.wikipedia.org/wiki/Transaction_isolation is 
 relevant here




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] StaleDataError/ObjectDeletedError

2014-02-01 Thread lars van gemerden
Ok, Michael,

That helped a lot, what i have done is (for future reference/others);

1) turned of autoflush on all sessions,
2) shortened the lifespan of session to a minimum,
3) removed the if object_session(obj): session.merge(obj) option in the 
Session() function,

This seems to have solved the problem for now (needs more testing)!

Thanks for the link to the talk as well.

Cheerio, Lars



On Saturday, February 1, 2014 4:34:10 PM UTC+1, Michael Bayer wrote:


 On Feb 1, 2014, at 9:01 AM, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote: 

  Oh, on more question: 
  
  might there be anything inherently wrong with the scoped_session 
 approach that i showed in the code snippets above? 

 the code which illustrates the @contextmanager and the “def Session()” 
 looks error-prone and entirely awkward, and the rationale for such a 
 context manager isn’t apparent.   

 It appears to be mixing the intent of wishing to share random rows between 
 multiple sessions (a bad idea) while at the same time trying to conceal the 
 details of how a delicate operation like that is performed (it guesses 
 whether add() or merge() should be used, etc).  It also seems to mix the 
 concerns of dealing with object mechanics and session creation at the same 
 time which are typically two different concerns, not to mention that it has 
 a complex system of committing or not committing using flags which makes it 
 unsurprising that you’re seeing non-existent rows show up in other 
 transactions. 

 So yeah, if it were me, I’d definitely try to approach whatever the 
 problem is it’s trying to solve in a different way, one which preferably 
 sticks to the patterns outlined in the ORM tutorial as much as possible 
 (e.g. one session at a time, load/manipulate objects, commit(), throw 
 everything away).   Those points at which an application actually uses two 
 sessions at once, or transfers objects between them, should be very 
 isolated cases with very explicit mechanics and clear rationale why this 
 operation is needed in this specific case (where typical cases are: sending 
 objects into worker threads or processes, moving objects in and out of 
 caching layers, or running two transactions simultaneously so that one can 
 commit and the other roll back, such as a transaction writing to an 
 application history table).The app wouldn’t have a generic “here’s one 
 of those places we need to use two sessions with a specific target object 
 to pull out of one of them” use case such that a context manager is needed, 
 there should be extremely few places where that kind of thing goes on. 

 The kind of issue you’re hitting is exactly the one I talk about in detail 
 in my talk, “The SQLAlchemy Session in Depth”: 
 http://techspot.zzzeek.org/2012/11/14/pycon-canada-the-sqlalchemy-session-in-depth/
  Page 18 of the PDF illustrates a slide “Lack of Behavioral Constraints 
 Creates Confusion” illustrating an anti-pattern similar to the one I think 
 we’re seeing here. 



-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] StaleDataError/ObjectDeletedError

2014-01-31 Thread lars van gemerden
Hi Michael,

With some more detail:

What i do is:
1 make a new object (mapped)- obj1
2 create a scoped session (with context manager)- session1
3 do session1.add(obj) 
4 create another scoped session - session2 
5 do session2.query(someclass).get(some_id)-obj2 
6 close session2, no commit, no flush - obj2 is detached (right?)
7 do obj1.someattr.append(obj2)
8 do session1.commit()
9 get the first ERROR above 

basically i use

def Session( objs):
session = session_maker()
for obj in objs:
if object_session(obj) is None:
session.add(obj)
else:
session.merge(obj)
return session

@contextmanager
def scoped_session(objs = [], commit = True):
session = Session(objs)
try:
yield session
if commit:
session.commit()
except:
session.rollback()
raise
finally:
session.close()

and essentially code description (1-8) above comes down to:

obj1 = cls1()

with scoped_session([obj1]) as session1:
obj1.somefield = somevalue
with scoped_session(commit = False) as session2:
obj2 = session2.query(cls2).get(some_id)
obj1.someattr.append(obj2)

if i just do:

with scoped_session([obj1]) as session1:
obj1.somefield = somevalue

there is no problem.

Also:

this means an object was meant to be UPDATEed via the ORM, however the row 
which is the target of the UPDATE is missing.  Either the primary key of 
this row changed somehow, or the row was deleted, *or* the row is not 
visible to your transaction (this seems to be your case).

-  could the error also occur when the object was never committed to the 
database (which seems to be the case; the commit where the error occurs 
should be the first time the Company object is committed to the database)?
-  this seems to suggest that it is possible that a row is in the database, 
but that it is not visible to a transaction; is that possible?

As far as i know in the code that causes the problem, i do not do any 
deletes and i do not call flush myself.

Doing some more testing, now i get more of the second error in:

def __str__(self): #in mapped class
print object_session(self) is not None, has_identity(self) # True, 
True, = OK
print self.id #= ERROR
..

with trace:
File d:\Documents\Code\python\floware\models\flow\processes.py, line 333, 
in run
  self.execute(input, output)
File d:\Documents\Code\python\floware\toolshed\logs.py, line 55, in 
wrapper
  f_result = func(*v, **k)
File d:\Documents\Code\python\floware\models\flow\libraries\basic.py, 
line 159, in execute
  print %s %s % (self.cursor, str(i.item))
File d:\Documents\Code\python\floware\models\data\database.py, line 281, 
in __str__
  print object_session(self), has_identity(self), self.id
File 
C:\python27\lib\site-packages\sqlalchemy-0.8.3-py2.7-win32.egg\sqlalchemy\orm\attributes.py,
 
line 316, in __get__
File 
C:\python27\lib\site-packages\sqlalchemy-0.8.3-py2.7-win32.egg\sqlalchemy\orm\attributes.py,
 
line 611, in get
File 
C:\python27\lib\site-packages\sqlalchemy-0.8.3-py2.7-win32.egg\sqlalchemy\orm\state.py,
 
line 380, in __call__
File 
C:\python27\lib\site-packages\sqlalchemy-0.8.3-py2.7-win32.egg\sqlalchemy\orm\loading.py,
 
line 606, in load_scalar_attributes

sqlalchemy.orm.exc.ObjectDeletedError: Instance 'Company at 0x5e4a3f0' 
has been deleted, or its row is otherwise not present.

CL




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] keyword search

2013-12-17 Thread lars van gemerden
Hi all,

I want to implement a keyword search over multiple fields and/or even 
related tables. Tables/orm classes are not designed by me but by users of 
my software, so i will probably let them indicate whether a 
field/relationship should be included (or I'll base it on type, e.g. String 
and Text fields only).

I was thinking of using a hybrid property, but they seem a bit to magical 
for this purpose (might be really slow). Is there a best practice/standard 
way to do this in SQLA?

Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] Re: keyword search

2013-12-17 Thread lars van gemerden
PS: a search over all fields would be great too!

On Tuesday, December 17, 2013 11:01:51 AM UTC+1, lars van gemerden wrote:

 Hi all,

 I want to implement a keyword search over multiple fields and/or even 
 related tables. Tables/orm classes are not designed by me but by users of 
 my software, so i will probably let them indicate whether a 
 field/relationship should be included (or I'll base it on type, e.g. String 
 and Text fields only).

 I was thinking of using a hybrid property, but they seem a bit to magical 
 for this purpose (might be really slow). Is there a best practice/standard 
 way to do this in SQLA?

 Cheers, Lars


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] nullable/association question

2013-11-21 Thread lars van Gemerden
Hi Michael,

since i might also start with a Role instance and add User instances to
them i need a symmetrical solution with regard ref and backref (and i
think  casade_backrefs=False
would not work in that case?).

So i tested two solutions which both seem to work in this specific case:

 - create a separate session for the query on Role
(session.query(Role).all()); not the same session the User instance is in
(as i did before)
 - set autoflush to false on the query as in
(session.query(Role).autoflush(False).all())

Since you did not mention the second solution, i wondered whether there are
possible disadvantages to the second approach; the first one seems slower
but cleaner.

Cheers, Lars


On Wed, Nov 20, 2013 at 4:51 PM, Michael Bayer mike...@zzzcomputing.comwrote:

 you either want to prevent User from being cascaded and/or added into the
 Session ahead of time, which if this is occurring via backref you might
 want to look at casade_backrefs=False (
 http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html?highlight=cascade_backrefs#controlling-cascade-on-backrefs).
  If not that, then use “with session.no_autoflush” for the period of
 time that you query for Role.




 On Nov 20, 2013, at 8:02 AM, lars van gemerden l...@rational-it.com
 wrote:

 Hi all,

 I have 2 sqla classes with mapped tables: User and Role with a many to
 many relationship (User.roles/Role.users) through an association table.
 User has columns email and password, both non nullable.

 I create an instance of User but do not commit it yet, next i do a query
 on Role: session.query(Role).all() (to be able to let an end-user choose
 one or more roles for the for the newly created User).

 This gives the error: IntegrityError: (IntegrityError) User.email may not
 be NULL u'INSERT INTO User (_created_, discriminator, email, password)
 VALUES (CURRENT_TIMESTAMP, ?, ?, ?)' (None, None, None)

 I think the query tries to flush the instance of User, which causes the
 error.

 My questions is: Why and how do i avoid it? I just want a list of all
 roles currently in the Role table to be able to assign one or moe to the
 User instance.

 Cheers, Lars



 --
 You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to sqlalchemy+unsubscr...@googlegroups.com.

 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.





-- 

Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] just a picture

2013-11-21 Thread Lars van Gemerden
The tool


Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


 On 21 nov. 2013, at 15:02, Stefane Fermigier s...@fermigier.com wrote:
 
 Hi Lars,
 
 Are you working on the tool, or on the application whose schema is depicted 
 on the tool ?
 
 Regards,
 
   S.
 
 On Nov 21, 2013, at 1:38 PM, lars van gemerden wrote:
 
 something i have been working on, running on sqlalchemy .
 
 
 
 Cheers, Lars
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 Stefane Fermigier - http://fermigier.com/ - http://twitter.com/sfermigier - 
 http://linkedin.com/in/sfermigier
 Founder  CEO, Abilian - Enterprise Social Software - http://www.abilian.com/
 Co-Founder and Chairman, Systematic FreeOSS Special Interest Group - 
 http://www.gt-logiciel-libre.org/
 Co-Founder  Vice-President, National Council for FreeOSS - http://cnll.fr/
 Vice President, Open World Forum 2013 - http://openworldforum.org/
 Well done is better than well said. - Benjamin Franklin
 There's no such thing as can't. You always have a choice. - Ken Gor
 Le vrai courage, c'est de faire ce qui est juste. - Dr Benjamin Justice
 
 
 
 -- 
 You received this message because you are subscribed to a topic in the Google 
 Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/01K5mYOcFSE/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] just a picture

2013-11-21 Thread Lars van Gemerden
No, sorry, to be able to do this, a lot of of settings are predetermined (the 
modeller can set nullable, unique, validation, etc, but not settings like 
cascades). The goal is to make a modelling tool that can run on existing db 
engines and persist python objects representing 'business' data, not to be a 
modelling tool with the reach of sqla itself.

Cheers, Lars


Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


 On 21 nov. 2013, at 15:19, Werner werner...@gmx.ch wrote:
 
 On 21/11/2013 15:02, Stefane Fermigier wrote:
 Hi Lars,
 
 Are you working on the tool, or on the application whose schema is depicted 
 on the tool ?
 Assuming it is a tool this would be very nice.
 
 Can it read an existing SA model?
 
 Werner
 
 -- 
 You received this message because you are subscribed to a topic in the Google 
 Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/01K5mYOcFSE/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] just a picture

2013-11-21 Thread lars van gemerden


something i have been working on, running on sqlalchemy .

https://lh4.googleusercontent.com/-xwar8HEk2iU/Uo39bYo9x_I/AD4/AoTurWbGJ30/s1600/dbpic.png
Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] nullable/association question

2013-11-21 Thread lars van gemerden
in my application the query for roles is practically impossible to get into 
the block (close to) where the user instance is created, i could not attach 
the User instance to a session at all (before being ready to commit), but 
would i still be able to set the roles on the User?

CL

On Thursday, November 21, 2013 3:57:44 PM UTC+1, Michael Bayer wrote:

 I’d stick with judicious use of “with session.no_autoflush: around the 
 block where the User is being constructed and isn’t ready to flush yet.


 On Nov 21, 2013, at 6:29 AM, lars van Gemerden 
 la...@rational-it.comjavascript: 
 wrote:

 Hi Michael,

 since i might also start with a Role instance and add User instances to 
 them i need a symmetrical solution with regard ref and backref (and i think  
 casade_backrefs=False 
 would not work in that case?).

 So i tested two solutions which both seem to work in this specific case:

  - create a separate session for the query on Role 
 (session.query(Role).all()); not the same session the User instance is in 
 (as i did before)
  - set autoflush to false on the query as in 
 (session.query(Role).autoflush(False).all())

 Since you did not mention the second solution, i wondered whether there 
 are possible disadvantages to the second approach; the first one seems 
 slower but cleaner.

 Cheers, Lars


 On Wed, Nov 20, 2013 at 4:51 PM, Michael Bayer 
 mik...@zzzcomputing.comjavascript:
  wrote:

 you either want to prevent User from being cascaded and/or added into the 
 Session ahead of time, which if this is occurring via backref you might 
 want to look at casade_backrefs=False (
 http://docs.sqlalchemy.org/en/rel_0_9/orm/session.html?highlight=cascade_backrefs#controlling-cascade-on-backrefs).
  
  If not that, then use “with session.no_autoflush” for the period of 
 time that you query for Role.




 On Nov 20, 2013, at 8:02 AM, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote:

 Hi all,

 I have 2 sqla classes with mapped tables: User and Role with a many to 
 many relationship (User.roles/Role.users) through an association table. 
 User has columns email and password, both non nullable.

 I create an instance of User but do not commit it yet, next i do a query 
 on Role: session.query(Role).all() (to be able to let an end-user choose 
 one or more roles for the for the newly created User).

 This gives the error: IntegrityError: (IntegrityError) User.email may not 
 be NULL u'INSERT INTO User (_created_, discriminator, email, password) 
 VALUES (CURRENT_TIMESTAMP, ?, ?, ?)' (None, None, None)

 I think the query tries to flush the instance of User, which causes the 
 error.

 My questions is: Why and how do i avoid it? I just want a list of all 
 roles currently in the Role table to be able to assign one or moe to the 
 User instance.

 Cheers, Lars



 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+...@googlegroups.com javascript:.

 To post to this group, send email to sqlal...@googlegroups.comjavascript:
 .
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.





 -- 
 
 Lars van Gemerden
 la...@rational-it.com javascript:
 +31 6 26 88 55 39
  

 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+...@googlegroups.com javascript:.
 To post to this group, send email to sqlal...@googlegroups.comjavascript:
 .
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] nullable/association question

2013-11-20 Thread lars van gemerden
Hi all,

I have 2 sqla classes with mapped tables: User and Role with a many to many 
relationship (User.roles/Role.users) through an association table. User has 
columns email and password, both non nullable.

I create an instance of User but do not commit it yet, next i do a query on 
Role: session.query(Role).all() (to be able to let an end-user choose one 
or more roles for the for the newly created User).

This gives the error: IntegrityError: (IntegrityError) User.email may not 
be NULL u'INSERT INTO User (_created_, discriminator, email, password) 
VALUES (CURRENT_TIMESTAMP, ?, ?, ?)' (None, None, None)

I think the query tries to flush the instance of User, which causes the 
error.

My questions is: Why and how do i avoid it? I just want a list of all roles 
currently in the Role table to be able to assign one or moe to the User 
instance.

Cheers, Lars


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] quick query question

2013-10-28 Thread lars van gemerden
Hi,

Short question: when does e.g. query.all() returns a list of objects and 
when it returns a list of NamedTuple's?

is it only after you call add_columns() on the query that all() starts 
returning NamedTuple's? 

Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] quick query question

2013-10-28 Thread Lars van Gemerden
Thanks again ..


Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


 On 28 okt. 2013, at 18:12, Michael Bayer mike...@zzzcomputing.com wrote:
 
 the list of objects are for when the query is set to return exactly one 
 mapped class.  query.column_descriptions will show this.
 
 
 On Oct 28, 2013, at 12:44 PM, lars van gemerden l...@rational-it.com wrote:
 
 Hi,
 
 Short question: when does e.g. query.all() returns a list of objects and 
 when it returns a list of NamedTuple's?
 
 is it only after you call add_columns() on the query that all() starts 
 returning NamedTuple's? 
 
 Cheers, Lars
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 -- 
 You received this message because you are subscribed to a topic in the Google 
 Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/If3XeRoBh6w/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] quelified/disambiguated column names in query

2013-10-22 Thread lars van Gemerden
Thank you,

i must have blundered over that in the docs ...

Lars


On Mon, Oct 21, 2013 at 11:36 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Oct 21, 2013, at 5:20 PM, lars van gemerden l...@rational-it.com
 wrote:

 Hello,

 Say that i have a table with reports with a column 'title' and a one to
 many relationship 'chapters' to chapters also with a column 'title', if i
 join these tables in a query, like:

 q =
 self.session.query(Report).join(Report.chapters).add_columns(Report.title,
 Chapter.title, Chapter.text)
 for p in q.all():
 print p.title

 print p.title prints the title of the chapter.

 Is there a way to let the query.all() return NamedTuples with
 qualified/disambiguated  names (either 'title' and 'chapters.title' or
 'Report.title' and 'Chapter.title' or perhaps with underscores), because
 now i see no way to distinguish the columns (apart maybe from the order).

 p.keys() returns 'title' twice.


 use labels:

 add_columns(Report.title.label(report_title),
 Chapter.title.label(chapter_title))





 Cheers, Lars

 PS: i am using sqla 0.7.5

 --
 You received this message because you are subscribed to the Google Groups
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an
 email to sqlalchemy+unsubscr...@googlegroups.com.

 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.





-- 

Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] quelified/disambiguated column names in query

2013-10-21 Thread lars van gemerden
Hello,

Say that i have a table with reports with a column 'title' and a one to 
many relationship 'chapters' to chapters also with a column 'title', if i 
join these tables in a query, like:

q = 
self.session.query(Report).join(Report.chapters).add_columns(Report.title, 
Chapter.title, Chapter.text)
for p in q.all():
print p.title

print p.title prints the title of the chapter.

Is there a way to let the query.all() return NamedTuples with 
qualified/disambiguated  names (either 'title' and 'chapters.title' or 
'Report.title' and 'Chapter.title' or perhaps with underscores), because 
now i see no way to distinguish the columns (apart maybe from the order).

p.keys() returns 'title' twice.

Cheers, Lars

PS: i am using sqla 0.7.5

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] query question

2013-09-09 Thread lars van gemerden
Ok, i've tried both (and each separately), as in:

r1 = Report(number = 1, title = The Bird) 
r2 = Report(number = 2, title = The Bucket)
session.add_all([r1, r2])
session.commit()
q = self.session.query(Report.title)
q.with_entities(Report.number)
q.add_columns(Report.number)
print q.all()

printing:

[(u'The Bird',), (u'The Bucket',)]

what i would like to see is:

   [(u'The Bird', 1), (u'The Bucket', 2)]
 
or something similar.

Cheers, Lars

On Wednesday, September 4, 2013 1:24:28 PM UTC+2, Simon King wrote:

 On Wed, Sep 4, 2013 at 12:05 PM, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote: 
  I  think i must be reading over something, but: 
  
  is there a way to delay the selection of attributes in a query; 
 something 
  like 
  
session.query(Person).filter(Person.age  
  100).select(Person.name).first() 
  
 (uAncient Bob,) 
  

 I'm not sure quite what you mean, but the with_entities method of 
 Query would seem to be the closest to your example: 

   
 http://docs.sqlalchemy.org/en/rel_0_8/orm/query.html#sqlalchemy.orm.query.Query.with_entities
  

 I assume you know you can also do this: 

   session.query(Person.name).filter(Person.age  100).first() 

 You can also defer certain columns so that they will be loaded lazily: 

   
 http://docs.sqlalchemy.org/en/rel_0_8/orm/mapper_config.html#deferred-column-loading
  

 Hope that helps, 

 Simon 


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] query question

2013-09-09 Thread lars van Gemerden
OK, never mind |-)

should be:

   q = q.with_entities(Report.number)
   q = q.add_columns(Report.number)

sry



On Mon, Sep 9, 2013 at 2:43 PM, lars van gemerden l...@rational-it.comwrote:

 Ok, i've tried both (and each separately), as in:

 r1 = Report(number = 1, title = The Bird)
 r2 = Report(number = 2, title = The Bucket)
 session.add_all([r1, r2])
 session.commit()
 q = self.session.query(Report.title)
 q.with_entities(Report.number)
 q.add_columns(Report.number)
 print q.all()

 printing:

 [(u'The Bird',), (u'The Bucket',)]

 what i would like to see is:

[(u'The Bird', 1), (u'The Bucket', 2)]

 or something similar.

 Cheers, Lars

 On Wednesday, September 4, 2013 1:24:28 PM UTC+2, Simon King wrote:

 On Wed, Sep 4, 2013 at 12:05 PM, lars van gemerden la...@rational-it.com
 wrote:
  I  think i must be reading over something, but:
 
  is there a way to delay the selection of attributes in a query;
 something
  like
 
session.query(Person).filter(**Person.age 
  100).select(Person.name).**first()
 
 (uAncient Bob,)
 

 I'm not sure quite what you mean, but the with_entities method of
 Query would seem to be the closest to your example:

   http://docs.sqlalchemy.org/en/**rel_0_8/orm/query.html#**
 sqlalchemy.orm.query.Query.**with_entitieshttp://docs.sqlalchemy.org/en/rel_0_8/orm/query.html#sqlalchemy.orm.query.Query.with_entities

 I assume you know you can also do this:

   session.query(Person.name).**filter(Person.age  100).first()

 You can also defer certain columns so that they will be loaded lazily:

   http://docs.sqlalchemy.org/en/**rel_0_8/orm/mapper_config.**
 html#deferred-column-loadinghttp://docs.sqlalchemy.org/en/rel_0_8/orm/mapper_config.html#deferred-column-loading

 Hope that helps,

 Simon

  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/7hA4UZV8uaA/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.




-- 

Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] query question

2013-09-04 Thread lars van gemerden
I  think i must be reading over something, but:

is there a way to delay the selection of attributes in a query; something 
like

  session.query(Person).filter(Person.age  
100).select(Person.name).first()

   (uAncient Bob,)

Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] error related to setting attribute to same value twice

2013-09-03 Thread lars van gemerden
I am getting that same error (not the original one). For the moment i've 
solved the problem in a different way, but it might pop up again. I'll keep 
merge in mind (i've run into the is already attached to session before).

Thank you, Lars 

On Monday, September 2, 2013 9:18:11 PM UTC+2, Simon King wrote:

 Dunno, let's try it: 

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

 Base = declarative_base() 

 class Person(Base): 
 __tablename__ = 'people' 
 id = sa.Column(sa.Integer, primary_key=True, autoincrement=True) 
 name = sa.Column(sa.String(20)) 

 if __name__ == '__main__': 
 engine = sa.create_engine('sqlite:///:memory:') 
 Base.metadata.create_all(engine) 
 Session = saorm.sessionmaker(bind=engine) 

 # Create our first session and use it to add a Person to the database 
 sess1 = Session() 
 sess1.add(Person(name='lars')) 
 sess1.commit() 
 sess1.close() 

 # Retrieve our Person from the database again. 
 person = sess1.query(Person).first() 

 # Now try to add that instance to a second session 
 sess2 = Session() 
 sess2.add(person) 
 sess2.commit() 


 Output: 

 Traceback (most recent call last): 
... 
 sqlalchemy.exc.InvalidRequestError: Object 'Person at 0x10c9f5790' is 
 already attached to session '1' (this is '2') 

 Looks very similar to your error message. I'm using SA 0.8.0 - it looks 
 like the message is slightly different in your version. 

 The correct thing to do in this case is to use session.merge to create a 
 copy of the object, attached to the new session. If you change the last few 
 lines of the script above to: 

 sess2 = Session() 
 merged = sess2.merge(person) 
 sess2.add(merged) 

 ...it works fine. 

 Hope that helps, 

 Simon 

 On 2 Sep 2013, at 19:58, lars van Gemerden 
 la...@rational-it.comjavascript: 
 wrote: 

  Yes I know the question was a bit vague, but i couldn't think of a 
 simple way to show some code. A test case would probably require some major 
 surgery; I'll consider it though. 
  
  It is possible that the second instance is associated with a different 
 session, i'd have to check. What actually happens if you add the same 
 instance to a second session? 
  
  CL 
  
  
  On Mon, Sep 2, 2013 at 8:23 PM, Simon King 
  si...@simonking.org.ukjavascript: 
 wrote: 
  Without knowing your application it's very difficult to know... 
  
  Is there any chance that the second object is already associated with a 
 different session? Perhaps from a different thread, or retrieved from a 
 cache or something similar? 
  
  Producing a standalone test script would help in diagnosing the problem. 
  
  Simon 
  
  
  On 2 Sep 2013, at 18:56, Lars van Gemerden 
  la...@rational-it.comjavascript: 
 wrote: 
  
   Well, from the message yes, but i am not setting any primary keys 
 manually, so where could the second instance come from? 
   
   CL 
   
    
   Lars van Gemerden 
   la...@rational-it.com javascript: 
   +31 6 26 88 55 39 
    
   
   On 2 sep. 2013, at 17:39, Simon King 
   si...@simonking.org.ukjavascript: 
 wrote: 
   
   On Mon, Sep 2, 2013 at 4:01 PM, lars van gemerden 
 la...@rational-it.com javascript: wrote: 
   Hi all, 
   
   I have a one-to-one and many-to-one relationship (with an 
 association table 
   in the middle; Report.author-assoctable-Person.reports; why the 
 table in the 
   middle, you might ask, well it's a long story) and i am setting the 
 author 
   on a specific Report twice to the same value. This gives the 
 following 
   error: 
   
InvalidRequestError: Can't attach instance person at 
 0x36a9350; 
   another instance with key (class 'models.data.classes.person', 
 (2,)) is 
   already present in this session. 
   
   The first time i set the author, it works and if i change the author 
 it 
   works as well. 
   
   This seems i little strange to me, why not be able to set the 
 attribute to 
   the same value twice? 
   
   Otherwise i have to check whether the new and old values are equal 
 (which 
   through the peculiarties of my code is somewhat wastefull) 
   
   
   I think the message is actually telling you that you have 2 different 
   instances of your person class with the same primary key. 
 SQLAlchemy 
   uses an identity map to ensure that a particular row in the database 
   is only identified by a single instance within a particular session. 
   If you violate that assumption (eg. by loading one instance of 
   person from the database, then creating another instance and 
 setting 
   its primary key), you will get errors like this. 
   
   Does that sound plausible? 
   
   Simon 
   
   -- 
   You received this message because you are subscribed to a topic in 
 the Google Groups sqlalchemy group. 
   To unsubscribe from this topic, visit 
 https://groups.google.com/d

Re: [sqlalchemy] error related to setting attribute to same value twice

2013-09-03 Thread lars van Gemerden
My version is 0.7.5 (thought i was on 8 already), i will look at updating!

The error sounds similar, I'll get back on this after i do (after some
research to find out if updating is a good idea right now)

Cheers, Lars




On Tue, Sep 3, 2013 at 11:38 AM, Simon King si...@simonking.org.uk wrote:

 I realised after I sent that script that I wasn't reproducing quite
 the same situation. I should have loaded the person from the database
 in sess2 as well, before trying to add the instance from sess1. In
 other words, change the end of the test script to say:

 sess2 = Session()
 dupe = sess2.query(Person).first()
 sess2.add(person)
 sess2.commit()

 So sess2 now contains an instance representing that database row. The
 error message is now:

 AssertionError: A conflicting state is already present in the identity
 map for key (class '__main__.Person', (1,))

 ...which is still not quite the same as your error message. What
 version of SQLAlchemy are you using? (The above was from 0.8.2)

 Simon

 On Tue, Sep 3, 2013 at 10:15 AM, lars van gemerden l...@rational-it.com
 wrote:
  I am getting that same error (not the original one). For the moment i've
  solved the problem in a different way, but it might pop up again. I'll
 keep
  merge in mind (i've run into the is already attached to session
 before).
 
  Thank you, Lars
 
 
  On Monday, September 2, 2013 9:18:11 PM UTC+2, Simon King wrote:
 
  Dunno, let's try it:
 
  import sqlalchemy as sa
  import sqlalchemy.orm as saorm
  from sqlalchemy.ext.declarative import declarative_base
 
  Base = declarative_base()
 
  class Person(Base):
  __tablename__ = 'people'
  id = sa.Column(sa.Integer, primary_key=True, autoincrement=True)
  name = sa.Column(sa.String(20))
 
  if __name__ == '__main__':
  engine = sa.create_engine('sqlite:///:memory:')
  Base.metadata.create_all(engine)
  Session = saorm.sessionmaker(bind=engine)
 
  # Create our first session and use it to add a Person to the
 database
  sess1 = Session()
  sess1.add(Person(name='lars'))
  sess1.commit()
  sess1.close()
 
  # Retrieve our Person from the database again.
  person = sess1.query(Person).first()
 
  # Now try to add that instance to a second session
  sess2 = Session()
  sess2.add(person)
  sess2.commit()
 
 
  Output:
 
  Traceback (most recent call last):
 ...
  sqlalchemy.exc.InvalidRequestError: Object 'Person at 0x10c9f5790' is
  already attached to session '1' (this is '2')
 
  Looks very similar to your error message. I'm using SA 0.8.0 - it looks
  like the message is slightly different in your version.
 
  The correct thing to do in this case is to use session.merge to
 create a
  copy of the object, attached to the new session. If you change the last
 few
  lines of the script above to:
 
  sess2 = Session()
  merged = sess2.merge(person)
  sess2.add(merged)
 
  ...it works fine.
 
  Hope that helps,
 
  Simon
 
  On 2 Sep 2013, at 19:58, lars van Gemerden la...@rational-it.com
 wrote:
 
   Yes I know the question was a bit vague, but i couldn't think of a
   simple way to show some code. A test case would probably require some
 major
   surgery; I'll consider it though.
  
   It is possible that the second instance is associated with a different
   session, i'd have to check. What actually happens if you add the same
   instance to a second session?
  
   CL
  
  
   On Mon, Sep 2, 2013 at 8:23 PM, Simon King si...@simonking.org.uk
   wrote:
   Without knowing your application it's very difficult to know...
  
   Is there any chance that the second object is already associated with
 a
   different session? Perhaps from a different thread, or retrieved from
 a
   cache or something similar?
  
   Producing a standalone test script would help in diagnosing the
 problem.
  
   Simon
  
  
   On 2 Sep 2013, at 18:56, Lars van Gemerden la...@rational-it.com
   wrote:
  
Well, from the message yes, but i am not setting any primary keys
manually, so where could the second instance come from?
   
CL
   

Lars van Gemerden
la...@rational-it.com
+31 6 26 88 55 39

   
On 2 sep. 2013, at 17:39, Simon King si...@simonking.org.uk
 wrote:
   
On Mon, Sep 2, 2013 at 4:01 PM, lars van gemerden
la...@rational-it.com wrote:
Hi all,
   
I have a one-to-one and many-to-one relationship (with an
association table
in the middle; Report.author-assoctable-Person.reports; why the
table in the
middle, you might ask, well it's a long story) and i am setting
 the
author
on a specific Report twice to the same value. This gives the
following
error:
   
 InvalidRequestError: Can't attach instance person at
0x36a9350;
another instance with key (class 'models.data.classes.person',
(2,)) is
already present in this session

[sqlalchemy] error related to setting attribute to same value twice

2013-09-02 Thread lars van gemerden
Hi all,

I have a one-to-one and many-to-one relationship (with an association table 
in the middle; Report.author-assoctable-Person.reports; why the table in 
the middle, you might ask, well it's a long story) and i am setting the 
author on a specific Report twice to the same value. This gives the 
following error:

   InvalidRequestError: Can't attach instance person at 
0x36a9350; another instance with key (class 
'models.data.classes.person', (2,)) is already present in this session.

The first time i set the author, it works and if i change the author it 
works as well.

This seems i little strange to me, why not be able to set the attribute to 
the same value twice?

Otherwise i have to check whether the new and old values are equal (which 
through the peculiarties of my code is somewhat wastefull) 

Cheers, Lars 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] error related to setting attribute to same value twice

2013-09-02 Thread Lars van Gemerden
Well, from the message yes, but i am not setting any primary keys manually, so 
where could the second instance come from?

CL


Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


On 2 sep. 2013, at 17:39, Simon King si...@simonking.org.uk wrote:

 On Mon, Sep 2, 2013 at 4:01 PM, lars van gemerden l...@rational-it.com 
 wrote:
 Hi all,
 
 I have a one-to-one and many-to-one relationship (with an association table
 in the middle; Report.author-assoctable-Person.reports; why the table in the
 middle, you might ask, well it's a long story) and i am setting the author
 on a specific Report twice to the same value. This gives the following
 error:
 
   InvalidRequestError: Can't attach instance person at 0x36a9350;
 another instance with key (class 'models.data.classes.person', (2,)) is
 already present in this session.
 
 The first time i set the author, it works and if i change the author it
 works as well.
 
 This seems i little strange to me, why not be able to set the attribute to
 the same value twice?
 
 Otherwise i have to check whether the new and old values are equal (which
 through the peculiarties of my code is somewhat wastefull)
 
 
 I think the message is actually telling you that you have 2 different
 instances of your person class with the same primary key. SQLAlchemy
 uses an identity map to ensure that a particular row in the database
 is only identified by a single instance within a particular session.
 If you violate that assumption (eg. by loading one instance of
 person from the database, then creating another instance and setting
 its primary key), you will get errors like this.
 
 Does that sound plausible?
 
 Simon
 
 -- 
 You received this message because you are subscribed to a topic in the Google 
 Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/bkm3-nB6d1o/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] error related to setting attribute to same value twice

2013-09-02 Thread lars van Gemerden
Yes I know the question was a bit vague, but i couldn't think of a simple
way to show some code. A test case would probably require some major
surgery; I'll consider it though.

It is possible that the second instance is associated with a different
session, i'd have to check. What actually happens if you add the same
instance to a second session?

CL


On Mon, Sep 2, 2013 at 8:23 PM, Simon King si...@simonking.org.uk wrote:

 Without knowing your application it's very difficult to know...

 Is there any chance that the second object is already associated with a
 different session? Perhaps from a different thread, or retrieved from a
 cache or something similar?

 Producing a standalone test script would help in diagnosing the problem.

 Simon


 On 2 Sep 2013, at 18:56, Lars van Gemerden l...@rational-it.com wrote:

  Well, from the message yes, but i am not setting any primary keys
 manually, so where could the second instance come from?
 
  CL
 
  
  Lars van Gemerden
  l...@rational-it.com
  +31 6 26 88 55 39
  
 
  On 2 sep. 2013, at 17:39, Simon King si...@simonking.org.uk wrote:
 
  On Mon, Sep 2, 2013 at 4:01 PM, lars van gemerden l...@rational-it.com
 wrote:
  Hi all,
 
  I have a one-to-one and many-to-one relationship (with an association
 table
  in the middle; Report.author-assoctable-Person.reports; why the table
 in the
  middle, you might ask, well it's a long story) and i am setting the
 author
  on a specific Report twice to the same value. This gives the following
  error:
 
   InvalidRequestError: Can't attach instance person at
 0x36a9350;
  another instance with key (class 'models.data.classes.person', (2,))
 is
  already present in this session.
 
  The first time i set the author, it works and if i change the author it
  works as well.
 
  This seems i little strange to me, why not be able to set the
 attribute to
  the same value twice?
 
  Otherwise i have to check whether the new and old values are equal
 (which
  through the peculiarties of my code is somewhat wastefull)
 
 
  I think the message is actually telling you that you have 2 different
  instances of your person class with the same primary key. SQLAlchemy
  uses an identity map to ensure that a particular row in the database
  is only identified by a single instance within a particular session.
  If you violate that assumption (eg. by loading one instance of
  person from the database, then creating another instance and setting
  its primary key), you will get errors like this.
 
  Does that sound plausible?
 
  Simon
 
  --
  You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
  To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/bkm3-nB6d1o/unsubscribe.
  To unsubscribe from this group and all its topics, send an email to
 sqlalchemy+unsubscr...@googlegroups.com.
  To post to this group, send email to sqlalchemy@googlegroups.com.
  Visit this group at http://groups.google.com/group/sqlalchemy.
  For more options, visit https://groups.google.com/groups/opt_out.
 
  --
  You received this message because you are subscribed to the Google
 Groups sqlalchemy group.
  To unsubscribe from this group and stop receiving emails from it, send
 an email to sqlalchemy+unsubscr...@googlegroups.com.
  To post to this group, send email to sqlalchemy@googlegroups.com.
  Visit this group at http://groups.google.com/group/sqlalchemy.
  For more options, visit https://groups.google.com/groups/opt_out.

 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/bkm3-nB6d1o/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.




-- 

Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


[sqlalchemy] alternate way to filter queries

2013-08-26 Thread lars van gemerden
Hi all,

This might be a bit of a stretch but here it goes:

Say that i have a lambda function that takes a mapped object and teturns 
whether it is valid; e.g:

lambda person: person.age  17 or person.length  1.75

is it possible to use this method to perform an sqla query on the database? 
Perhaps by using hybrid_method?

Cheers, Lars

PS: this might seem strange question, but it would save me a lot of work 
and/or would make my internal and user interfaces a lot more consistent. 

PPS: i do also have a string representation of the lambda functions, if 
that helps

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] alternate way to filter queries

2013-08-26 Thread lars van gemerden
Hi Michael,

So just to be sure, if i understand correctly and i have:

   func  = lambda person: person.age  17 or person.length  1.75

I can do:

   class Person(Base):
   # 

  @hybrid_method
  def run_filter(self, fn):
   return fn(self)

  session.query(MyClass).filter(MyClass.run_compare(func))

to get all objects of class Person where obj.age17 or obj.length1.75  

Is that without loading all records and filtering afterwards??

That's pretty impressive i think (and really helpful to me personally)

Cheers, Lars



On Monday, August 26, 2013 5:23:07 PM UTC+2, Michael Bayer wrote:


 On Aug 26, 2013, at 11:14 AM, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote:

 Hi all,

 This might be a bit of a stretch but here it goes:

 Say that i have a lambda function that takes a mapped object and teturns 
 whether it is valid; e.g:

 lambda person: person.age  17 or person.length  1.75

 is it possible to use this method to perform an sqla query on the 
 database? Perhaps by using hybrid_method?

 Cheers, Lars

 PS: this might seem strange question, but it would save me a lot of work 
 and/or would make my internal and user interfaces a lot more consistent. 

 PPS: i do also have a string representation of the lambda functions, if 
 that helps



 I'm not sure if you need these to remain as lambdas, sure you can just 
 pass it to a hybrid_method:

 class MyClass(Base):
 # 

@hybrid_method
def run_compare(self, fn, *args):
 return fn(*args)


 query(MyClass).filter(MyClass.run_compare(some_lambda, some_other_object))


 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] alternate way to filter queries

2013-08-26 Thread lars van gemerden
Hmm, too bad. I do have the lambda methods in string form so i'll probably 
have to write a parser and construct the query with unions and intersects 
(or filter(A.b  1, A.c0) like calls instead of intersects).

No how did writing a parser tree go |-)?

CL

On Monday, August 26, 2013 8:27:16 PM UTC+2, Simon King wrote:


 On 26 Aug 2013, at 19:15, lars van gemerden 
 la...@rational-it.comjavascript: 
 wrote: 
  
  On Monday, August 26, 2013 5:23:07 PM UTC+2, Michael Bayer wrote: 
  
  On Aug 26, 2013, at 11:14 AM, lars van gemerden la...@rational-it.com 
 wrote: 
  
  Hi all, 
  
  This might be a bit of a stretch but here it goes: 
  
  Say that i have a lambda function that takes a mapped object and 
 teturns whether it is valid; e.g: 
  
  lambda person: person.age  17 or person.length  1.75 
  
  is it possible to use this method to perform an sqla query on the 
 database? Perhaps by using hybrid_method? 
  
  Cheers, Lars 
  
  PS: this might seem strange question, but it would save me a lot of 
 work and/or would make my internal and user interfaces a lot more 
 consistent. 
  
  PPS: i do also have a string representation of the lambda functions, if 
 that helps 
  
  
  I'm not sure if you need these to remain as lambdas, sure you can just 
 pass it to a hybrid_method: 
  
  class MyClass(Base): 
  #  
  
 @hybrid_method 
 def run_compare(self, fn, *args): 
  return fn(*args) 
  
  
  query(MyClass).filter(MyClass.run_compare(some_lambda, 
 some_other_object)) 
  

  
  Hi Michael, 
  
  So just to be sure, if i understand correctly and i have: 
  
 func  = lambda person: person.age  17 or person.length  1.75 
  
  I can do: 
  
 class Person(Base): 
 #  
  
@hybrid_method 
def run_filter(self, fn): 
 return fn(self) 
  
session.query(MyClass).filter(MyClass.run_compare(func)) 
  
  to get all objects of class Person where obj.age17 or obj.length1.75   
  
  Is that without loading all records and filtering afterwards?? 
  
  That's pretty impressive i think (and really helpful to me personally) 
  
  Cheers, Lars 


 As long as your function returns something meaningful when called with the 
 class (Person) rather than an instance, it should be fine. 

 Unfortunately I'm not sure your example will work, because expr or 
 expr isn't something that SQLAlchemy can convert into an SQL statement. 
 If you were able to use the bitwise or operator | instead, that would 
 do the right thing. See the contains and intersects methods in the 
 first example on 
 http://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/hybrid.html. 

 Hope that helps, 

 Simon

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.


Re: [sqlalchemy] possible bug in InstrumentedAttribute.__delete__?

2013-07-14 Thread lars van gemerden
Now i was doing both, but you're right, i can remove the default from the 
column definition, and just initialise the object with the default in 
__init__ (from metadata i created elsewhere, but will remain available). 
Setting the default ASAP (on object creation) seems like the way of least 
surprise and it's not hard to do, as Wichert mentioned.

Thanks again, Michael, my code improves ...

Lars

On Saturday, July 13, 2013 10:59:08 PM UTC+2, Michael Bayer wrote:


 On Jul 13, 2013, at 3:21 PM, Lars van Gemerden 
 la...@rational-it.comjavascript: 
 wrote: 

  Just trying to help; i am not sure, but what you might also consider is 
 to initialise attributes (or on first access) with a default if a default 
 value as Column argument is given (i am already doing this in my own code) 
 and also reset to this default in case of del, but maybe there are 
 disadvantages. 

 I can see why that might be reasonable, but at the same time the default 
 for Column is at the level of Core; the default could be a Python 
 callable, and this callable could be relying upon the fact that it is 
 invoked within the context of executing the INSERT statement.By pulling 
 out the Core-level default upon attribute access and just populating at 
 the ORM level means we bypass the Core in doing its normal job with 
 default, which violates . there's a term for this I can't recall, but 
 the idea is, A does job X using mechanism P therefore if, based on some 
 very non-deterministic system, once in awhile B does job X using mechanism 
 Q instead, it makes the code much harder to understand and debug.  So 
 to really do it this way, the contract of default in terms of the ORM 
 would need to be modified completely, such that *all* Column default args 
 are applied at the ORM level.   But even then, your Column() is still 
 behaving in two different ways based on if you use Session.add() or 
 engine.execute(insert()). 

 The original intent of default for Column is that it acts exactly like 
 server_default, except it runs on the Python side for the case that your 
 schema wasn't created with this default, or the functionality of your 
 default is not supported by the database.  But otherwise, just like a 
 server_default, the value is None on the Python side until the INSERT 
 occurs. 

 Really, a better solution here would be an ORM-level default, that's 
 what you've implemented anyway.   




-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] possible bug in InstrumentedAttribute.__delete__?

2013-07-13 Thread Lars van Gemerden
I think i didn't explain the error enough; just calling del user.name in the 
example below causes an exception (except when i already accessed (say print 
user.name) the attribute, which seemed odd to me). This is independent of 
whether the attr becomes None. 

Otherwise it isn't a real problem in my code, just something i ran into while 
cleaning up some internal api, as you say i can easily work around it.

Cheers, Lars




Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


On 13 jul. 2013, at 01:52, Michael Bayer mike...@zzzcomputing.com wrote:

 There's all kinds of things that __delete__ should possibly do, most likely 
 just do what you expect, i.e. set the value to NULL, but this would be 
 changing its behavior in a very backwards-incompatible way; such a change 
 could only be considered for 0.9.
 
 Whats not clear is how exactly an entire application was built around 0.7, 
 relying on del in some way such that this can no longer be changed, and 
 suddenly it's an issue?  doesn't make sense, I don't see why you can't just 
 get replace those del statements on your end.  It's not supported, and if 
 it were, it would not be in 0.7 or 0.8.
 
 
 
 On Jul 12, 2013, at 6:11 PM, Lars van Gemerden l...@rational-it.com wrote:
 
 After thinking on it some more, should InstrumentedAttribute.__delete__ even 
 exist then, or maybe raise a NotImplementedError?
 
 CL
 
 
 Lars van Gemerden
 l...@rational-it.com
 +31 6 26 88 55 39
 
 
 On 12 jul. 2013, at 18:28, Michael Bayer mike...@zzzcomputing.com wrote:
 
 We've never supported del obj.attrname as a means of setting an attribute 
 to None (which translates to NULL in SQL).   Setting the value to None 
 explicitly is preferred.
 
 On Jul 12, 2013, at 12:16 PM, lars van gemerden l...@rational-it.com 
 wrote:
 
 Hi all,
 
 I had an arror in my code and i think i have reconstructed it as follows:
 
 ---
 
 from sqlalchemy import Column, Integer, String
 from sqlalchemy import create_engine
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy.ext.declarative import declarative_base
 
 Base = declarative_base()
 engine = create_engine('sqlite:///:memory:', echo=True)
 Session = sessionmaker(bind=engine)
 
 class User(Base):
 __tablename__ = 'users'
 id = Column(Integer, primary_key=True)
 name = Column(String)
 
 Base.metadata.create_all(engine) 
 
 session = Session()
 user = User(name = 'bob')
 session.add(user)
 session.commit()
 #user.name
 del user.name #error in sqlalchemy file attributes.py line 529
 #user.name
 session.commit()
 assert user.name == None #error: user.name is still 'bob'
 
 
 
 These two errors do not occur if i access the attributes before the delete 
 or the commit (i.e. uncomment the #user.name lines).
 
 I am using version 7.5; are these errors solved by the latest version?
 
  I would like to avoid upgrading at this point, but if i could be 
 reasonably sure that upgrading solves the problem, then no problem ..
 
 Cheers, Lars
 
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 
 -- 
 You received this message because you are subscribed to a topic in the 
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/TRUmFTaDCF8/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 -- 
 You received this message because you are subscribed

Re: [sqlalchemy] possible bug in InstrumentedAttribute.__delete__?

2013-07-13 Thread Lars van Gemerden
Just trying to help; i am not sure, but what you might also consider is to 
initialise attributes (or on first access) with a default if a default value as 
Column argument is given (i am already doing this in my own code) and also 
reset to this default in case of del, but maybe there are disadvantages.

Cheers, Lars




Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


On 13 jul. 2013, at 20:02, Michael Bayer mike...@zzzcomputing.com wrote:

 
 On Jul 13, 2013, at 10:24 AM, Lars van Gemerden l...@rational-it.com wrote:
 
 I think i didn't explain the error enough; just calling del user.name in the 
 example below causes an exception (except when i already accessed (say print 
 user.name) the attribute, which seemed odd to me). This is independent of 
 whether the attr becomes None. 
 
 Otherwise it isn't a real problem in my code, just something i ran into 
 while cleaning up some internal api, as you say i can easily work around it.
 
 Great then, yes we don't do a good job with del but there is a logic to it 
 which I can't be 100% sure some apps aren't relying upon.I can possibly 
 make it behave intuitively for 0.9, I guess it should mean, set the 
 attribute to None - this because as you might have noticed an instrumented 
 column attribute defaults itself to None when first accessed.
 
 -- 
 You received this message because you are subscribed to a topic in the Google 
 Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/TRUmFTaDCF8/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] possible bug in InstrumentedAttribute.__delete__?

2013-07-12 Thread lars van gemerden
Hi all,

I had an arror in my code and i think i have reconstructed it as follows:

---

from sqlalchemy import Column, Integer, String
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()
engine = create_engine('sqlite:///:memory:', echo=True)
Session = sessionmaker(bind=engine)

class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)

Base.metadata.create_all(engine) 

session = Session()
user = User(name = 'bob')
session.add(user)
session.commit()
#user.name
del user.name #error in sqlalchemy file attributes.py line 529
#user.name
session.commit()
assert user.name == None #error: user.name is still 'bob'



These two errors do not occur if i access the attributes before the delete 
or the commit (i.e. uncomment the #user.name lines).

I am using version 7.5; are these errors solved by the latest version?

 I would like to avoid upgrading at this point, but if i could be 
reasonably sure that upgrading solves the problem, then no problem ..

Cheers, Lars


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] possible bug in InstrumentedAttribute.__delete__?

2013-07-12 Thread Lars van Gemerden
Can i just override __delattr__ in a subclass of a declarative base to achieve 
this anyway?

Cheers, Lars


Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


On 12 jul. 2013, at 18:28, Michael Bayer mike...@zzzcomputing.com wrote:

 We've never supported del obj.attrname as a means of setting an attribute 
 to None (which translates to NULL in SQL).   Setting the value to None 
 explicitly is preferred.
 
 On Jul 12, 2013, at 12:16 PM, lars van gemerden l...@rational-it.com wrote:
 
 Hi all,
 
 I had an arror in my code and i think i have reconstructed it as follows:
 
 ---
 
 from sqlalchemy import Column, Integer, String
 from sqlalchemy import create_engine
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy.ext.declarative import declarative_base
 
 Base = declarative_base()
 engine = create_engine('sqlite:///:memory:', echo=True)
 Session = sessionmaker(bind=engine)
 
 class User(Base):
 __tablename__ = 'users'
 id = Column(Integer, primary_key=True)
 name = Column(String)
 
 Base.metadata.create_all(engine) 
 
 session = Session()
 user = User(name = 'bob')
 session.add(user)
 session.commit()
 #user.name
 del user.name #error in sqlalchemy file attributes.py line 529
 #user.name
 session.commit()
 assert user.name == None #error: user.name is still 'bob'
 
 
 
 These two errors do not occur if i access the attributes before the delete 
 or the commit (i.e. uncomment the #user.name lines).
 
 I am using version 7.5; are these errors solved by the latest version?
 
  I would like to avoid upgrading at this point, but if i could be reasonably 
 sure that upgrading solves the problem, then no problem ..
 
 Cheers, Lars
 
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 -- 
 You received this message because you are subscribed to a topic in the Google 
 Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/TRUmFTaDCF8/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
  
  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] possible bug in InstrumentedAttribute.__delete__?

2013-07-12 Thread Lars van Gemerden
After thinking on it some more, should InstrumentedAttribute.__delete__ even 
exist then, or maybe raise a NotImplementedError?

CL


Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


On 12 jul. 2013, at 18:28, Michael Bayer mike...@zzzcomputing.com wrote:

 We've never supported del obj.attrname as a means of setting an attribute 
 to None (which translates to NULL in SQL).   Setting the value to None 
 explicitly is preferred.
 
 On Jul 12, 2013, at 12:16 PM, lars van gemerden l...@rational-it.com wrote:
 
 Hi all,
 
 I had an arror in my code and i think i have reconstructed it as follows:
 
 ---
 
 from sqlalchemy import Column, Integer, String
 from sqlalchemy import create_engine
 from sqlalchemy.orm import sessionmaker
 from sqlalchemy.ext.declarative import declarative_base
 
 Base = declarative_base()
 engine = create_engine('sqlite:///:memory:', echo=True)
 Session = sessionmaker(bind=engine)
 
 class User(Base):
 __tablename__ = 'users'
 id = Column(Integer, primary_key=True)
 name = Column(String)
 
 Base.metadata.create_all(engine) 
 
 session = Session()
 user = User(name = 'bob')
 session.add(user)
 session.commit()
 #user.name
 del user.name #error in sqlalchemy file attributes.py line 529
 #user.name
 session.commit()
 assert user.name == None #error: user.name is still 'bob'
 
 
 
 These two errors do not occur if i access the attributes before the delete 
 or the commit (i.e. uncomment the #user.name lines).
 
 I am using version 7.5; are these errors solved by the latest version?
 
  I would like to avoid upgrading at this point, but if i could be reasonably 
 sure that upgrading solves the problem, then no problem ..
 
 Cheers, Lars
 
 
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To unsubscribe from this group and stop receiving emails from it, send an 
 email to sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
 
 -- 
 You received this message because you are subscribed to a topic in the Google 
 Groups sqlalchemy group.
 To unsubscribe from this topic, visit 
 https://groups.google.com/d/topic/sqlalchemy/TRUmFTaDCF8/unsubscribe.
 To unsubscribe from this group and all its topics, send an email to 
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy.
 For more options, visit https://groups.google.com/groups/opt_out.
  
  

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/groups/opt_out.




Re: [sqlalchemy] finding table/column name of unique constraint failure

2013-05-21 Thread lars van Gemerden
Thanks, Michael


On Mon, May 20, 2013 at 12:52 AM, Michael Bayer mike...@zzzcomputing.comwrote:


 On May 19, 2013, at 4:39 AM, lars van gemerden l...@rational-it.com
 wrote:

  Hi all,
 
  I generate webpages in which end-users can input data that is stored in
 a database via sqla.The datamodel is not pre-defined but created by (other)
 users/designers.
 
  My question is how can i best let the end-user know which field contains
 the error if the end-user violates a unique constraint; e.g. if the user
 creates an account by filling in a username/password, the username must be
 unique so the user must get an error (username already exists oss) if he
 tries to fill in an existing username.
 
  If i commit the data, the exception thrown is somewhat cryptic (is the
 message created by sqla or the database?).
 
  Some related questions:
 
  - are there arguments in the exception i could use?
  - should i just query the table for the existence of the unique
 constrained value (i seem to remember that is impossible in the validate
 solution, so how else)?
 
  I might be able to come up with some sort of solution, but i am looking
 for a good/the best (structurally sound, not too slow, not overly complex)
 solution, also useable for other constraints (e.g. non-null, maybe other
 query/multi-record based constraints).

 the messages are generated by the database and the DBAPI in use,
 SQLAlchemy just passes them through.  There's no standardization for those
 messages, so if your target database isn't providing enough parseable
 information, you may need to do a quick query against the unique fields on
 the table first in order to produce validation logic.


 --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/taHEXCvX2p0/unsubscribe?hl=en
 .
 To unsubscribe from this group and all its topics, send an email to
 sqlalchemy+unsubscr...@googlegroups.com.
 To post to this group, send email to sqlalchemy@googlegroups.com.
 Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
 For more options, visit https://groups.google.com/groups/opt_out.





-- 

Lars van Gemerden
l...@rational-it.com
+31 6 26 88 55 39


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] finding table/column name of unique constraint failure

2013-05-19 Thread lars van gemerden
Hi all,

I generate webpages in which end-users can input data that is stored in a 
database via sqla.The datamodel is not pre-defined but created by (other) 
users/designers.   

My question is how can i best let the end-user know which field contains 
the error if the end-user violates a unique constraint; e.g. if the user 
creates an account by filling in a username/password, the username must be 
unique so the user must get an error (username already exists oss) if he 
tries to fill in an existing username.

If i commit the data, the exception thrown is somewhat cryptic (is the 
message created by sqla or the database?). 

Some related questions:

- are there arguments in the exception i could use?
- should i just query the table for the existence of the unique constrained 
value (i seem to remember that is impossible in the validate solution, so 
how else)?

I might be able to come up with some sort of solution, but i am looking for 
a good/the best (structurally sound, not too slow, not overly complex) 
solution, also useable for other constraints (e.g. non-null, maybe other 
query/multi-record based constraints). 

Cheers, Lars

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at http://groups.google.com/group/sqlalchemy?hl=en.
For more options, visit https://groups.google.com/groups/opt_out.




[sqlalchemy] adding validates() decorator after class creation

2013-01-04 Thread lars van gemerden
Hi,

I am trying to use validates() to dynamically add validation to my sqla 
classes, but i cannot figure out how to do this. I have read python 
decorator docs and docs n validates, but something escapes me (or it is 
just not possible).

A code snippet (this does not work):

def create_validators(self):  
for cls in self.itervalues():
names = tuple([fld.key() for fld in cls._type_.fields()])
def validator(obj, name, value):
if not cls._type_[name].validate(value):
raise ValueError(incorrect value '%s' for '%s' in 
'%s' % (str(value), name, cls.__name__))
return value
setattr(cls, 'validator', validates(*names)(validator)) #does 
NOT work

in which:

'self' is a dictionary of sqla classes, 
'cls' is an sqla class (derived from declarative_base(...)), 
'cls._type_' contains the information for (further) generation of 'cls' 
(e.g. cls._type_[name].validate(value) calls a validate method for value 
for a field (say String(50)) with name 'name')

The method above runs without problem, but the validator function is never 
called when setting field values. I have tried all alternatives i can think 
of, but maybe i am missing something basic.

Can anyone help?

Cheers, Lars




-- 
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/-/-F7Lqaw1AagJ.
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: adding validates() decorator after class creation

2013-01-04 Thread lars van gemerden
Perfect (almost ;-), thanks a lot!

for future reference, the attribute name (key) was needed 
in create_validator(cls) to access the correct validate method:

@staticmethod
def _create_validator(key, cls): 
def validate(target, value, oldvalue, initiator):
if not cls._type_[key].validate(value):
raise ValueError(incorrect value '%s' for '%s' in '%s' % 
(str(value), key, cls.__name__))
return validate

def create_validators(self):  
for cls in self.itervalues():
for fld in cls._type_.fields():
key = fld.key()
attribute = getattr(cls, key)
event.listen(attribute, set, self._create_validator(key, 
cls))
debug_print('created validator for %s in %s' % (key, 
cls.__name__))

-- 
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/-/I-TQaC4YCqYJ.
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: automating inheritance

2012-05-01 Thread lars van gemerden
Well thats the thing, my users will determine the data structure
(graphically) and it is hard to predict what they will come up with.
On the other hand, I am only building a prototype at the moment, so
speed issues (if not easily solved) will have to wait.

I'll stick with joined inheritance for now (though I'll probalby take
out the unique base class for all classes).

Thank you again for all the help,

Lars

On Apr 27, 3:59 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 concrete inheritance is very challenging overall, if you expect there to be 
 any kind of polymorphic interaction between the classes.     if you want to 
 query polymorphically then speed will be probably worse.   If you can do 
 without polymorphic and stick to each subclass directly it wont have an issue.

 Usually though if I'm inheriting more than two levels, I'll use joined 
 inheritance for level one-two then single table for all levels beyond that.  
  Depends on what you're trying to do.

 On Apr 27, 2012, at 3:05 AM, lars van gemerden wrote:







  Ok, so speed might become an issue for me as well;

  Do you think a similar metaclass approach would work for concrete 
  inheritance would work without major drawbacks (before i do a major 
  overhaul)?
  Is there any indication about how much faster concrete inheritance is, 
  compared to joined inheritance?

  Cheers, Lars

  On Friday, April 20, 2012 9:32:49 PM UTC+2, Michael Bayer wrote:

  On Apr 20, 2012, at 8:51 AM, lars van gemerden wrote:
   Ok, thank you, that helps, but now i cannot inherit from Engineer, as in:

   class BaseMixin(object):

       discriminator = Column(String(50))

       @declared_attr
       def __tablename__(cls):
           return cls.__name__
       @declared_attr
       def id(cls):
           return Column(Integer, primary_key = True)
       @declared_attr
       def __mapper_args__(cls):
           if not has_inherited_table(cls):
               return {'polymorphic_on': 'discriminator'}
           else:
               return {'polymorphic_identity': cls.__name__}

   class InheritMixin(BaseMixin):
       @declared_attr
       def id(cls):
           super_id = super(InheritMixin, cls).id
           return Column(Integer, ForeignKey(super_id), primary_key = True)

   class Person(BaseMixin, Base):
       name = Column(String(50))

   class Engineer(InheritMixin, Person):
       job = Column(String(50))

   class MasterEngineer(InheritMixin, Engineer):
       specialty = Column(String(50))

   Gives an MRO() error and if i would reverse the baseclasses (like class 
   Engineer(Person, InheritMixin):  ... ), the inheriting classes pick up 
   the wrong id.

   Do you see any solution for this?

  yeah I suppose if you're building out joined inheritance more than one 
  level then this becomes awkward.   I never use joined inh more than one 
  level because it has too much of an impact on queries.

  the metaclass as you mention is always the last resort when the various 
  declarative trickery reaches its limit.   I'm not thrilled about the 
  metaclass approach because it quickly gets confusing and shouldn't be 
  necessary.   though in this case without some extra mechanism on 
  declarative, such as a __pre_declare__() method of some kind, it might be 
  the only approach.

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



Re: [sqlalchemy] Re: automating inheritance

2012-04-27 Thread lars van gemerden
Ok, so speed might become an issue for me as well; 

Do you think a similar metaclass approach would work for concrete 
inheritance would work without major drawbacks (before i do a major 
overhaul)?
Is there any indication about how much faster concrete inheritance is, 
compared to joined inheritance?

Cheers, Lars

On Friday, April 20, 2012 9:32:49 PM UTC+2, Michael Bayer wrote:


 On Apr 20, 2012, at 8:51 AM, lars van gemerden wrote:

  Ok, thank you, that helps, but now i cannot inherit from Engineer, as in:
  
  class BaseMixin(object):
  
  discriminator = Column(String(50))
  
  @declared_attr
  def __tablename__(cls):
  return cls.__name__
  @declared_attr
  def id(cls):
  return Column(Integer, primary_key = True)
  @declared_attr
  def __mapper_args__(cls):
  if not has_inherited_table(cls):
  return {'polymorphic_on': 'discriminator'}
  else:
  return {'polymorphic_identity': cls.__name__}
  
  
  class InheritMixin(BaseMixin):
  @declared_attr
  def id(cls):
  super_id = super(InheritMixin, cls).id
  return Column(Integer, ForeignKey(super_id), primary_key = True)
  
  class Person(BaseMixin, Base):
  name = Column(String(50))
 
  class Engineer(InheritMixin, Person):
  job = Column(String(50))
  
  class MasterEngineer(InheritMixin, Engineer):
  specialty = Column(String(50))
  
  Gives an MRO() error and if i would reverse the baseclasses (like class 
 Engineer(Person, InheritMixin):  ... ), the inheriting classes pick up the 
 wrong id.
  
  Do you see any solution for this? 

 yeah I suppose if you're building out joined inheritance more than one 
 level then this becomes awkward.   I never use joined inh more than one 
 level because it has too much of an impact on queries.

 the metaclass as you mention is always the last resort when the various 
 declarative trickery reaches its limit.   I'm not thrilled about the 
 metaclass approach because it quickly gets confusing and shouldn't be 
 necessary.   though in this case without some extra mechanism on 
 declarative, such as a __pre_declare__() method of some kind, it might be 
 the only approach.



-- 
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/-/MH4tZazKT0EJ.
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: automating inheritance

2012-04-20 Thread lars van gemerden
this is the testcase:

from sqlalchemy import *
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.ext.declarative import declarative_base, declared_attr

engine = create_engine('sqlite:///:memory:', echo=False)
Base = declarative_base(bind = engine)
Session = sessionmaker(bind = engine)

def setup(engine):
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
return Session()

class InheritMixin(object):

@declared_attr
def __tablename__(cls):
return cls.__name__
@declared_attr
def id(cls):
if Base in cls.__bases__:
print 'base in id(cls): ', cls
return Column(Integer, primary_key = True)
else:
print 'in id(cls): ', cls, cls.__bases__[0]
return Column(Integer, ForeignKey(cls.__bases__[0].id),
primary_key = True)
@declared_attr
def __mapper_args__(cls):
if Base in cls.__bases__:
print 'base in __mapper_args__(cls): ', cls
return {'polymorphic_on': 'discriminator'}
else:
print 'in __mapper_args__(cls): ', cls, cls.__bases__[0],
cls.id, (cls.id is cls.__bases__[0].id)
return {'polymorphic_identity': cls.__name__}

class Person(Base, InheritMixin):
discriminator = Column(String(50))
name = Column(String(50))

class Engineer(Person):
job = Column(String(50))

if __name__ == '__main__':

session = setup(engine)
a = Person(name = 'ann')
b = Engineer(name = 'bob', job = 'car repair')
session.add_all([a, b])
session.commit()
people = session.query(Person).all()
print people

Note that i left out the 'inherit_condition', because without there is
already a problem:

base in id(cls):  class '__main__.Person'
base in mapper_args(cls):  class '__main__.Person'
in mapper_args(cls):  class '__main__.Engineer' class
'__main__.Person' Person.id True
Traceback (most recent call last):
  File D:\Documents\Code\Eclipse\workspace\process_data3\src
\little_tests2.py, line 40, in module
class Engineer(Person):
  File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py,
line 1336, in __init__
_as_declarative(cls, classname, cls.__dict__)
  File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py,
line 1329, in _as_declarative
**mapper_args)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\__init__.py,
line 1116, in mapper
return Mapper(class_, local_table, *args, **params)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line
197, in __init__
self._configure_inheritance()
  File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line
473, in _configure_inheritance
self.local_table)
  File C:\Python27\lib\site-packages\sqlalchemy\sql\util.py, line
303, in join_condition
between '%s' and '%s'.%s % (a.description, b.description, hint))
sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships
between 'Person' and 'Engineer'.

What am i missing?

Cheers, Lars


On Apr 19, 4:13 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 19, 2012, at 6:23 AM, lars van gemerden wrote:









  I am trying to my my joined inheritance code clearer, for the dynamic
  generation of sa classes and tried to do something like this:

  class InheritMixin(object):

     @declared_attr
     def __tablename__(cls):
         return cls.__name__
     @declared_attr
     def id(cls):
         if cls.__name__ == 'Object':
             return Column(Integer, primary_key = True)
         else:
             print 'in id: ', cls.__name__, cls.__bases__[0].__name__
             return Column(Integer,
  ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True)
     @declared_attr
     def __mapper_args__(cls):
         if cls.__name__ == 'Object':
             return {'polymorphic_on': 'discriminator'}
         else:
             print 'in mapper_args: ', cls.__name__,
  cls.__bases__[0].__name__
             return {'polymorphic_identity': cls.__name__,
                     'inherit_condition': (cls.id ==
  cls.__bases__[0].id)}

  Object = type('Object', (Base, InheritMixin), clsdict)

  Where Object should be the (not necessarily direct) baseclass of all
  inheriting classes. However I get errors: Mapper Mapper|person|person
  could not assemble any primary key columns for mapped table 'Join
  object on Object(65389120) and person(65428224)'  etc ..

 im not sure of the cause of that error, can you attach a full test case which 
 illustrates this message being generated ?



  I noticed that the method __mapper_args__(cls) is always called before
  id(cls) (which is never called, probably due to the error.

 the __mapper_args__(cls) method here directly calls upon .id, so if you see 
 .id() not being called it suggests some other form of .id is being used.

 Is it possible that Base or something else has a conflicting id attribute?



  Also, is there a way to add the discriminator column to the mixin (if
  i just directly add

Re: [sqlalchemy] Re: automating inheritance

2012-04-20 Thread lars van gemerden
Ok, thank you, that helps, but now i cannot inherit from Engineer, as in:

class BaseMixin(object):

discriminator = Column(String(50))

@declared_attr
def __tablename__(cls):
return cls.__name__
@declared_attr
def id(cls):
return Column(Integer, primary_key = True)
@declared_attr
def __mapper_args__(cls):
if not has_inherited_table(cls):
return {'polymorphic_on': 'discriminator'}
else:
return {'polymorphic_identity': cls.__name__}


class InheritMixin(BaseMixin):
@declared_attr
def id(cls):
super_id = super(InheritMixin, cls).id
return Column(Integer, ForeignKey(super_id), primary_key = True)

class Person(BaseMixin, Base):
name = Column(String(50))
   
class Engineer(InheritMixin, Person):
job = Column(String(50))

class MasterEngineer(InheritMixin, Engineer):
specialty = Column(String(50))

Gives an MRO() error and if i would reverse the baseclasses (like class 
Engineer(Person, InheritMixin):  ... ), the inheriting classes pick up the 
wrong id.

Do you see any solution for this? 

BTW: could i just move

@declared_attr
def __mapper_args__(cls):
return {'polymorphic_identity': cls.__name__}

to InheritMixin instead of doing the 'has_inherited_table' if-statement in 
BaseMixin?

Cheers, Lars


On Friday, April 20, 2012 12:41:28 PM UTC+2, Michael Bayer wrote:


 On Apr 20, 2012, at 4:59 AM, lars van gemerden wrote:

  this is the testcase:
  
  
  What am i missing?


 the issue here is one of Python inheritance mechanics.   Declarative calls 
 upon @declared_attr in terms of the class, that is, we look through the 
 class to find each @declared_attr, but when we find one, we invoke it by 
 just calling it as a method, that is, getattr(cls, name).   This works for 
 things like __mapper_args__ which remain as callable methods on classes 
 like Person, Engineer.   But id, when that is declared on Person is 
 immediately replaced with a mapping.   By the time you get to Engineer, the 
 id() method is gone.

 So for inheriting cases you need to build a mixin that is applied to every 
 subclass.  This makes sense because a mixin with a column on it implies 
 that the column is being associated only with that immediate class - if you 
 wanted a subclass to act as single table inheritance, you'd omit this 
 class.  In this case you want the same column on all subclasses.So you 
 can do it like this (note also using declarative.has_inherited_table 
 helper):

 class InheritMixin(object):

@declared_attr
def __tablename__(cls):
return cls.__name__

@declared_attr
def id(cls):
return Column(Integer, primary_key = True)

@declared_attr
def __mapper_args__(cls):
if not has_inherited_table(cls):
return {'polymorphic_on': 'discriminator'}
else:
return {'polymorphic_identity': cls.__name__}

 class Inherits(InheritMixin):
 @declared_attr
 def id(cls):
 super_id = super(Inherits, cls).id
 return Column(Integer, ForeignKey(super_id),primary_key = True)

 class Person(InheritMixin, Base):
discriminator = Column(String(50))
name = Column(String(50))

 class Engineer(Inherits, Person):
job = Column(String(50))


 this should be in the docs so I've added ticket #2471 to handle this.

  
  Cheers, Lars
  
  
  On Apr 19, 4:13 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  On Apr 19, 2012, at 6:23 AM, lars van gemerden wrote:
  
  
  
  
  
  
  
  
  
  I am trying to my my joined inheritance code clearer, for the dynamic
  generation of sa classes and tried to do something like this:
  
  class InheritMixin(object):
  
 @declared_attr
 def __tablename__(cls):
 return cls.__name__
 @declared_attr
 def id(cls):
 if cls.__name__ == 'Object':
 return Column(Integer, primary_key = True)
 else:
 print 'in id: ', cls.__name__, cls.__bases__[0].__name__
 return Column(Integer,
  ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True)
 @declared_attr
 def __mapper_args__(cls):
 if cls.__name__ == 'Object':
 return {'polymorphic_on': 'discriminator'}
 else:
 print 'in mapper_args: ', cls.__name__,
  cls.__bases__[0].__name__
 return {'polymorphic_identity': cls.__name__,
 'inherit_condition': (cls.id ==
  cls.__bases__[0].id)}
  
  Object = type('Object', (Base, InheritMixin), clsdict)
  
  Where Object should be the (not necessarily direct) baseclass of all
  inheriting classes. However I get errors: Mapper Mapper|person|person
  could not assemble any primary key columns for mapped table 'Join
  object on Object(65389120) and person(65428224)'  etc ..
  
  im not sure of the cause of that error, can you attach a full test case 
 which illustrates this message being generated ?
  
  
  
  I noticed

Re: [sqlalchemy] Re: automating inheritance

2012-04-20 Thread lars van gemerden
Hi Mike,

How about this approach with a custom metaclass; so far it works and seems 
the cleanest to me:

from sqlalchemy import *
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.ext.declarative import declarative_base, 
has_inherited_table, DeclarativeMeta

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

class InheritMeta(DeclarativeMeta):

def __init__(cls, name, bases, clsdict):
cls.__tablename__ = cls.__name__
if not has_inherited_table(cls):
cls.id = Column(Integer, primary_key = True)
cls.discriminator = Column(String(50))
cls.__mapper_args__ = {'polymorphic_on': 'discriminator'}
else:
cls.id = Column(Integer, ForeignKey(bases[0].id), primary_key = 
True)
cls.__mapper_args__ = {'polymorphic_identity': cls.__name__}
super(InheritMeta, cls).__init__(name, bases, clsdict)

InheritableBase = declarative_base(bind = engine, metaclass = InheritMeta)

class Person(InheritableBase):
name = Column(String(50))
   
class Engineer(Person):
job = Column(String(50))

class MasterEngineer(Engineer):
specialty = Column(String(50))


if __name__ == '__main__':
InheritableBase.metadata.create_all(engine)
session = sessionmaker(bind=engine)()

a = Person(name = 'ann')
b = Engineer(name = 'bob', job = 'car repair')
c = MasterEngineer(name = 'carl', job = 'car repair', specialty = 
'tires')
session.add_all([a, b, c])
session.commit()
people = session.query(Person).all()
print people

Do you see any drawbacks, gotchas for later on?

Regards, Lars

On Friday, April 20, 2012 12:41:28 PM UTC+2, Michael Bayer wrote:


 On Apr 20, 2012, at 4:59 AM, lars van gemerden wrote:

  this is the testcase:
  
  
  What am i missing?


 the issue here is one of Python inheritance mechanics.   Declarative calls 
 upon @declared_attr in terms of the class, that is, we look through the 
 class to find each @declared_attr, but when we find one, we invoke it by 
 just calling it as a method, that is, getattr(cls, name).   This works for 
 things like __mapper_args__ which remain as callable methods on classes 
 like Person, Engineer.   But id, when that is declared on Person is 
 immediately replaced with a mapping.   By the time you get to Engineer, the 
 id() method is gone.

 So for inheriting cases you need to build a mixin that is applied to every 
 subclass.  This makes sense because a mixin with a column on it implies 
 that the column is being associated only with that immediate class - if you 
 wanted a subclass to act as single table inheritance, you'd omit this 
 class.  In this case you want the same column on all subclasses.So you 
 can do it like this (note also using declarative.has_inherited_table 
 helper):

 class InheritMixin(object):

@declared_attr
def __tablename__(cls):
return cls.__name__

@declared_attr
def id(cls):
return Column(Integer, primary_key = True)

@declared_attr
def __mapper_args__(cls):
if not has_inherited_table(cls):
return {'polymorphic_on': 'discriminator'}
else:
return {'polymorphic_identity': cls.__name__}

 class Inherits(InheritMixin):
 @declared_attr
 def id(cls):
 super_id = super(Inherits, cls).id
 return Column(Integer, ForeignKey(super_id),primary_key = True)

 class Person(InheritMixin, Base):
discriminator = Column(String(50))
name = Column(String(50))

 class Engineer(Inherits, Person):
job = Column(String(50))


 this should be in the docs so I've added ticket #2471 to handle this.

  
  Cheers, Lars
  
  
  On Apr 19, 4:13 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  On Apr 19, 2012, at 6:23 AM, lars van gemerden wrote:
  
  
  
  
  
  
  
  
  
  I am trying to my my joined inheritance code clearer, for the dynamic
  generation of sa classes and tried to do something like this:
  
  class InheritMixin(object):
  
 @declared_attr
 def __tablename__(cls):
 return cls.__name__
 @declared_attr
 def id(cls):
 if cls.__name__ == 'Object':
 return Column(Integer, primary_key = True)
 else:
 print 'in id: ', cls.__name__, cls.__bases__[0].__name__
 return Column(Integer,
  ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True)
 @declared_attr
 def __mapper_args__(cls):
 if cls.__name__ == 'Object':
 return {'polymorphic_on': 'discriminator'}
 else:
 print 'in mapper_args: ', cls.__name__,
  cls.__bases__[0].__name__
 return {'polymorphic_identity': cls.__name__,
 'inherit_condition': (cls.id ==
  cls.__bases__[0].id)}
  
  Object = type('Object', (Base, InheritMixin), clsdict)
  
  Where Object should be the (not necessarily direct) baseclass of all
  inheriting classes. However I get errors: Mapper Mapper|person|person

[sqlalchemy] automating inheritance

2012-04-19 Thread lars van gemerden
I am trying to my my joined inheritance code clearer, for the dynamic
generation of sa classes and tried to do something like this:


class InheritMixin(object):

@declared_attr
def __tablename__(cls):
return cls.__name__
@declared_attr
def id(cls):
if cls.__name__ == 'Object':
return Column(Integer, primary_key = True)
else:
print 'in id: ', cls.__name__, cls.__bases__[0].__name__
return Column(Integer,
ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True)
@declared_attr
def __mapper_args__(cls):
if cls.__name__ == 'Object':
return {'polymorphic_on': 'discriminator'}
else:
print 'in mapper_args: ', cls.__name__,
cls.__bases__[0].__name__
return {'polymorphic_identity': cls.__name__,
'inherit_condition': (cls.id ==
cls.__bases__[0].id)}

Object = type('Object', (Base, InheritMixin), clsdict)

Where Object should be the (not necessarily direct) baseclass of all
inheriting classes. However I get errors: Mapper Mapper|person|person
could not assemble any primary key columns for mapped table 'Join
object on Object(65389120) and person(65428224)'  etc ..

I noticed that the method __mapper_args__(cls) is always called before
id(cls) (which is never called, probably due to the error.

Is there some way to fix this, while keeping the inheritance code in a
mixin?

Also, is there a way to add the discriminator column to the mixin (if
i just directly add it to the declaration, this gave another maybe
related error)?

Cheers, Lars

-- 
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: dynamically adding a validates method

2012-04-16 Thread lars van gemerden
Thank you, i got it working now. For future reference:

Before creating a sa class with something like:

type(typename, (Base,), classdict)

I first create the classdict in which I define columns, __tablename__,
etc, and validators (relationships I add later).

The validators i create(using a subclass of dict as classdict in the
type() call, and typedef being an object holding the definition to be
used to create a sa class/table) with:

def createValidator(self, typedef):
# get names of attributes to be validated:
names = [attr.name for attr in typedef.attributes \
   if attr.validates()]
#create validator method from validating method in the
attr
#definition in typedef:
def validator(obj, name, value):
return typedef[name].validate(value)
#turn into sa @validate descriptor (i don't get the
#mechanics completely, but still):
validates(*names)(validator)
#add to classdict
self['validator'] = validator

Hope this helps someone, open to questions ...

Cheers, Lars

On Apr 15, 7:20 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 If you can't establish the event at class declaration time, then the 
 @event.listens_for/event.listen() paradigm 
 (seehttp://docs.sqlalchemy.org/en/latest/core/event.htmlfor background) can 
 be applied to the class-bound attribute (which here is Positive.value) at 
 any time.  Positive.value is an attribute generated by the mapping which is 
 a result of using the declarative base.

 On Apr 15, 2012, at 1:10 PM, lars van gemerden wrote:







  OK, this helps, so how do i do this if i do not know the name of the
  attribute to be checked  in advance(the value in
  @validates(value) )?

  On Apr 15, 6:52 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  using type() is equivalent to using a class declaration.   The end result 
  is the same, as are the mechanics of what goes on both from a Python as 
  well as a SQLAlchemy perspective.  So this works:

  Positive = type(Positive, (Base,), dict(__tablename__ =
  positives,  value = Column(Integer)))

  @event.listens_for(Positive.value, set)
  def checkvalue(target, value, oldvalue, initiator)
     assert value  0

  and also, since type() is equivalent to a class declaration, you can still 
  use @validates,  if you pass the function into the class dictionary, so 
  that it is part of the class before declarative sends it off to mapper():

  @validates(value)
  def checkvalue(self, name, value):
      assert value  0
      return value

  Positive = type(Positive, (Base,), dict(__tablename__ =
  positives,  value = Column(Integer), checkvalue=checkvalue))

  On Apr 15, 2012, at 12:37 PM, lars van gemerden wrote:

  I don't know what @validates hangs a marker of the method that
  mapper() uses when it instruments the class means. I guess my
  question now becomes: How do I add the event.listens_for descriptor to
  the class, since i do not have a class declaration in the traditional
  sense?

  On Apr 15, 4:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  @validates hangs a marker of the method that mapper() uses when it 
  instruments the class, so if the class is already mapped then that train 
  has left the station.   Taking a cab instead, you can just add the 
  attribute event directly:

  @event.listens_for(Positive.value, set)
  def checkvalue(target, value, oldvalue, initiator)
     assert value  0

  if you want to return a new, mutated value then add retval=True to 
  listens_for().

  On Apr 15, 2012, at 8:22 AM, lars van gemerden wrote:

  Hi,

  I need a way to dynamically add a validates method to a already
  created sqla class.

  In a normal class declaration you can add a validator by:

  class Positive(Base):
     __tablename__ = positives
     value = Column(Integer)

     def checkvalue(self, name, value):
         assert value  0
         return value
     validates(value)(checkvalue)

  However if you get the class dynamically:

  Positive = type(Positive, (Base,), dict(__tablename__ =
  positives,  value = Column(Integer)))

  I can't figure out how to add the validator, either in the type() call
  or afterwards.

  Cheers, Lars

  --
  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 
  athttp://groups.google.com/group/sqlalchemy?hl=en.

  --
  You

[sqlalchemy] Re: dynamically adding a validates method

2012-04-16 Thread lars van gemerden
PS: the validate(value) method in typedef[name] is a normal method,
throwing exception on errors and returning the value when OK.

On Apr 16, 2:01 pm, lars van gemerden l...@rational-it.com wrote:
 Thank you, i got it working now. For future reference:

 Before creating a sa class with something like:

     type(typename, (Base,), classdict)

 I first create the classdict in which I define columns, __tablename__,
 etc, and validators (relationships I add later).

 The validators i create(using a subclass of dict as classdict in the
 type() call, and typedef being an object holding the definition to be
 used to create a sa class/table) with:

     def createValidator(self, typedef):
             # get names of attributes to be validated:
             names = [attr.name for attr in typedef.attributes \
                        if attr.validates()]
             #create validator method from validating method in the
 attr
             #definition in typedef:
             def validator(obj, name, value):
                 return typedef[name].validate(value)
             #turn into sa @validate descriptor (i don't get the
             #mechanics completely, but still):
             validates(*names)(validator)
             #add to classdict
             self['validator'] = validator

 Hope this helps someone, open to questions ...

 Cheers, Lars

 On Apr 15, 7:20 pm, Michael Bayer mike...@zzzcomputing.com wrote:







  If you can't establish the event at class declaration time, then the 
  @event.listens_for/event.listen() paradigm 
  (seehttp://docs.sqlalchemy.org/en/latest/core/event.htmlforbackground) can 
  be applied to the class-bound attribute (which here is Positive.value) at 
  any time.  Positive.value is an attribute generated by the mapping which 
  is a result of using the declarative base.

  On Apr 15, 2012, at 1:10 PM, lars van gemerden wrote:

   OK, this helps, so how do i do this if i do not know the name of the
   attribute to be checked  in advance(the value in
   @validates(value) )?

   On Apr 15, 6:52 pm, Michael Bayer mike...@zzzcomputing.com wrote:
   using type() is equivalent to using a class declaration.   The end 
   result is the same, as are the mechanics of what goes on both from a 
   Python as well as a SQLAlchemy perspective.  So this works:

   Positive = type(Positive, (Base,), dict(__tablename__ =
   positives,  value = Column(Integer)))

   @event.listens_for(Positive.value, set)
   def checkvalue(target, value, oldvalue, initiator)
      assert value  0

   and also, since type() is equivalent to a class declaration, you can 
   still use @validates,  if you pass the function into the class 
   dictionary, so that it is part of the class before declarative sends it 
   off to mapper():

   @validates(value)
   def checkvalue(self, name, value):
       assert value  0
       return value

   Positive = type(Positive, (Base,), dict(__tablename__ =
   positives,  value = Column(Integer), checkvalue=checkvalue))

   On Apr 15, 2012, at 12:37 PM, lars van gemerden wrote:

   I don't know what @validates hangs a marker of the method that
   mapper() uses when it instruments the class means. I guess my
   question now becomes: How do I add the event.listens_for descriptor to
   the class, since i do not have a class declaration in the traditional
   sense?

   On Apr 15, 4:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
   @validates hangs a marker of the method that mapper() uses when it 
   instruments the class, so if the class is already mapped then that 
   train has left the station.   Taking a cab instead, you can just add 
   the attribute event directly:

   @event.listens_for(Positive.value, set)
   def checkvalue(target, value, oldvalue, initiator)
      assert value  0

   if you want to return a new, mutated value then add retval=True to 
   listens_for().

   On Apr 15, 2012, at 8:22 AM, lars van gemerden wrote:

   Hi,

   I need a way to dynamically add a validates method to a already
   created sqla class.

   In a normal class declaration you can add a validator by:

   class Positive(Base):
      __tablename__ = positives
      value = Column(Integer)

      def checkvalue(self, name, value):
          assert value  0
          return value
      validates(value)(checkvalue)

   However if you get the class dynamically:

   Positive = type(Positive, (Base,), dict(__tablename__ =
   positives,  value = Column(Integer)))

   I can't figure out how to add the validator, either in the type() call
   or afterwards.

   Cheers, Lars

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

[sqlalchemy] dynamically adding a validates method

2012-04-15 Thread lars van gemerden
Hi,

I need a way to dynamically add a validates method to a already
created sqla class.

In a normal class declaration you can add a validator by:

class Positive(Base):
__tablename__ = positives
value = Column(Integer)

def checkvalue(self, name, value):
assert value  0
return value
validates(value)(checkvalue)

However if you get the class dynamically:

Positive = type(Positive, (Base,), dict(__tablename__ =
positives,  value = Column(Integer)))

I can't figure out how to add the validator, either in the type() call
or afterwards.

Cheers, Lars

-- 
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: dynamically adding a validates method

2012-04-15 Thread lars van gemerden
I don't know what @validates hangs a marker of the method that
mapper() uses when it instruments the class means. I guess my
question now becomes: How do I add the event.listens_for descriptor to
the class, since i do not have a class declaration in the traditional
sense?



On Apr 15, 4:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 @validates hangs a marker of the method that mapper() uses when it 
 instruments the class, so if the class is already mapped then that train has 
 left the station.   Taking a cab instead, you can just add the attribute 
 event directly:

 @event.listens_for(Positive.value, set)
 def checkvalue(target, value, oldvalue, initiator)
    assert value  0

 if you want to return a new, mutated value then add retval=True to 
 listens_for().

 On Apr 15, 2012, at 8:22 AM, lars van gemerden wrote:







  Hi,

  I need a way to dynamically add a validates method to a already
  created sqla class.

  In a normal class declaration you can add a validator by:

  class Positive(Base):
     __tablename__ = positives
     value = Column(Integer)

     def checkvalue(self, name, value):
         assert value  0
         return value
     validates(value)(checkvalue)

  However if you get the class dynamically:

  Positive = type(Positive, (Base,), dict(__tablename__ =
  positives,  value = Column(Integer)))

  I can't figure out how to add the validator, either in the type() call
  or afterwards.

  Cheers, Lars

  --
  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: dynamically adding a validates method

2012-04-15 Thread lars van gemerden
OK, this helps, so how do i do this if i do not know the name of the
attribute to be checked  in advance(the value in
@validates(value) )?



On Apr 15, 6:52 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 using type() is equivalent to using a class declaration.   The end result is 
 the same, as are the mechanics of what goes on both from a Python as well as 
 a SQLAlchemy perspective.  So this works:

 Positive = type(Positive, (Base,), dict(__tablename__ =
 positives,  value = Column(Integer)))

 @event.listens_for(Positive.value, set)
 def checkvalue(target, value, oldvalue, initiator)
    assert value  0

 and also, since type() is equivalent to a class declaration, you can still 
 use @validates,  if you pass the function into the class dictionary, so that 
 it is part of the class before declarative sends it off to mapper():

 @validates(value)
 def checkvalue(self, name, value):
     assert value  0
     return value

 Positive = type(Positive, (Base,), dict(__tablename__ =
 positives,  value = Column(Integer), checkvalue=checkvalue))

 On Apr 15, 2012, at 12:37 PM, lars van gemerden wrote:







  I don't know what @validates hangs a marker of the method that
  mapper() uses when it instruments the class means. I guess my
  question now becomes: How do I add the event.listens_for descriptor to
  the class, since i do not have a class declaration in the traditional
  sense?

  On Apr 15, 4:29 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  @validates hangs a marker of the method that mapper() uses when it 
  instruments the class, so if the class is already mapped then that train 
  has left the station.   Taking a cab instead, you can just add the 
  attribute event directly:

  @event.listens_for(Positive.value, set)
  def checkvalue(target, value, oldvalue, initiator)
     assert value  0

  if you want to return a new, mutated value then add retval=True to 
  listens_for().

  On Apr 15, 2012, at 8:22 AM, lars van gemerden wrote:

  Hi,

  I need a way to dynamically add a validates method to a already
  created sqla class.

  In a normal class declaration you can add a validator by:

  class Positive(Base):
     __tablename__ = positives
     value = Column(Integer)

     def checkvalue(self, name, value):
         assert value  0
         return value
     validates(value)(checkvalue)

  However if you get the class dynamically:

  Positive = type(Positive, (Base,), dict(__tablename__ =
  positives,  value = Column(Integer)))

  I can't figure out how to add the validator, either in the type() call
  or afterwards.

  Cheers, Lars

  --
  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 
  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: append to children in hierarchical data

2012-04-12 Thread lars van gemerden
The question was based on a misconception on my part  (in a visual
representation of a tree, while dragging a node you drag the whole
subtree with it, so you can't drop a node in it's own subtree).

Sorry about that ...


PS: Checked that when updating the children (via append) the exception
occurs right away (is there a flush happening in the background?),
while when updating the parent, the exception happens during the flush
afterwards.

On Apr 11, 5:41 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 11, 2012, at 3:34 AM, lars van gemerden wrote:









  Hi all,

  I am looking for a way to append a child to a tree like structure. I
  am using adjacency to represent the tree.

  Let's say I have a relationship configured with:

  children = relationship(TreeNode,
                                  primaryjoin = TreeNode.id ==
  TreeNode.parent_id,
                                  backref = backref( parent,
  remote_side=[TreeNode.id]),
                                  cascade = all, delete-orphan,
                                  use_list = True)

  and I do:

    t1 = TreeNode()
    t2 = TreeNode(parent = t1)
    t3 = TreeNode(parent = t2)

  then i can set:

    t1.parent = t3,

  without problem, but:

    t3.children.append(t1)

  gives a CircularDependencyError, while i would like this to give the
  same result as t1.parent = t3, perhaps by altering the behaviour of
  Treenode.children.append.

  Am I missing something?
  Is there some way to arrange for this?

 t1.parent = t3 means you aren't persisting a tree anymore - it's no longer a 
 hierarchy, since t3 is a descendant of t1 already via t2.   It's a cycle.

 The exception on the children side is probably because mutating children 
 has the effect of both t3 and t1 being considered in the flush (due to 
 t3.children as well as t1.parent_id changing), whereas t1.parent = t3 does 
 not actually consider t3 to modified.   You'd still get a cycle if you 
 created everything via x.parent=y at once (below I just put it into the 
 adjacency_list.py example - boom):

     node = TreeNode('rootnode')
     n1 = TreeNode('node1', parent=node)
     n2 = TreeNode('node2', parent=n1)
     node.parent = n2
     session.add(node)
     session.flush()

 sqlalchemy.exc.CircularDependencyError: Circular dependency detected. Cycles: 
  ...

 though I wasn't able to reproduce the behavior being different by mutating 
 children vs. the parentI'm sure with more digging I could figure that 
 out.   But in any case, you aren't safe from cycles if you're building them, 
 the usual way to insert rows with cycles to themselves is to use the 
 post_update feature described 
 athttp://docs.sqlalchemy.org/en/latest/orm/relationships.html#rows-that   
  You probably need to put it on both sides in this case as the unit of work 
 code will consider one or both of the children or parent relationships in 
 a particular flush depending on where it sees changes.

-- 
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] append to children in hierarchical data

2012-04-11 Thread lars van gemerden
Hi all,

I am looking for a way to append a child to a tree like structure. I
am using adjacency to represent the tree.

Let's say I have a relationship configured with:

children = relationship(TreeNode,
 primaryjoin = TreeNode.id ==
TreeNode.parent_id,
 backref = backref( parent,
remote_side=[TreeNode.id]),
 cascade = all, delete-orphan,
 use_list = True)

and I do:

   t1 = TreeNode()
   t2 = TreeNode(parent = t1)
   t3 = TreeNode(parent = t2)

then i can set:

   t1.parent = t3,

without problem, but:

   t3.children.append(t1)

gives a CircularDependencyError, while i would like this to give the
same result as t1.parent = t3, perhaps by altering the behaviour of
Treenode.children.append.

Am I missing something?
Is there some way to arrange for this?

Cheers, Lars



-- 
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: return type of relationship

2012-03-30 Thread lars van gemerden
Thanks,

Is there a more direct way to do this for the Column return type as
well? Now i have:

@staticmethod
def column(cls, name):
for cl in cls.mro():
if hasattr(cl, '__table__'):
for c in cl.__table__.c:
if c.name == name: return c

@staticmethod
def type(obj, name):
try:
return XSALfactory.column(type(obj),
name).type.python_type
except AttributeError:
return type(getattr(obj, name))

(Without the relationship type implemented yet.)


On Mar 30, 1:38 am, Michael Bayer mike...@zzzcomputing.com wrote:
 we're working on a more documented API for getting info like this but at the 
 moment it would be:

 MyClass.someattribute.property.mapper.class_

 On Mar 29, 2012, at 7:16 PM, lars van gemerden wrote:







  I am generating xml from SAclass objects and need to get the return
  type (referred SA class)  of an relationship attribute (even if the
  returned value is None). The type will be used as tagname during XML
  generation.

  Can anyone tell me how to get this type?

  Cheers, Lars

  --
  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: help on SAWarning

2012-03-30 Thread lars van gemerden
Found another bug and the warning is gone; can't pinpoint why
though ...

On Mar 30, 1:03 am, lars van gemerden l...@rational-it.com wrote:
 OK, thanks, I still get the warning in some cases and i am still
 zooming in on the problem for a small test case.

 At least i have solved the problem of the id of InstrumentedLists
 changing after commit(by bypassing one layer of recursion in the xml
 tree parsing, i am not looking up the id of the IList anymore).
 Cheers

 On Mar 29, 4:20 pm, Michael Bayer mike...@zzzcomputing.com wrote:







  On Mar 29, 2012, at 9:50 AM, lars van gemerden wrote:

   I have found that this specific behaviour (re-initialization of the
   InstrumentedList) does not happen if expire_on_commit = False is set
   on the sesssion. However this leads to other errors in my code.

   I guess I don't quite understand why expire would be called after a
   commit; shouldn't the commit result in the session being perfectly
   synchronized with the DB?

  It does.  The expire of the attributes doesn't cause any SQL to be emitted 
  until you access the attributes, in which case a new transaction is begun 
  (note the DBAPI's default mode of operation is to always be in a 
  transaction, and SQLAlchemy does not challenge this).  In between your 
  commit() and the start of a new transaction, any amount of state within the 
  database may have been changed by other transactions.

  If expire_on_commit=False is leading to errors, that would imply that this 
  is actually happening in your case.

-- 
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: help on SAWarning

2012-03-29 Thread lars van gemerden
I think I have an odd case of the first possibility you mentioned:

I am generating XML from SAclass objects opdating these objects from
XML. To detect cyclic references and double objects, I maintain a
registry of objects based on id() (reg[str(id(obj))] = obj). The id is
stored as the attribute ID in the XML tag. When updating the objects
I first look them up in the registry obj = reg[etree.get(ID)] and
update them afterwards. I do this as well with relationships/
InstrumentedLists (but not with database fields like Integer).

What I noticed was that InstrumentedList changes id() after a commit
(with a = Address(), Address.persons = relationship(...) ):

print id(a), id(a.persons), id(a.persons[0])
session.commit()
print id(a), id(a.persons), id(a.persons[0])

gives:

47148168 47174264 47114112
47148168 47175784 47114112 (the middle id has changed)

So I assume that after a commit a new InstrumentedList is created.

- Could it be conceivable that is causes the warning mentioned
above(an old version of the InstrumentedList being updated with an
valid SAclass object)?
- Is there a way to get around this new INstrumetnedList being
created?

Cheers, Lars



On Mar 29, 1:53 am, Michael Bayer mike...@zzzcomputing.com wrote:
 you've got a situation like this:

 ft = session.query(FieldType).first()

 f = Field()
 ft.of_members.append(f)

 assert f in session  # normally returns True, assuming normal cascade on 
 of_members

 session.expunge(f)  # remove f from the session

 session.flush()   # generates warning, since ft.of_members has changed but 
 the contents aren't in the Session

 Another cause could be, of_members has a cascade that doesn't include 
 save-update, like cascade='delete' is a common mistake.

 On Mar 28, 2012, at 6:45 PM, lars van gemerden wrote:







  Hi all,

  I am getting the error: SAWarning: Object of type Field not in
  session, add operation along 'FieldType.of_members' will not proceed
  and have no idea where to start looking for the error. Can anyone help
  me with some idea of why this warning occurs or what direction to look
  in order to fix it?

  The warning occurs only during the first call of a specific method,
  while i think i reset everything (e.g. dropping all tables in the
  database) between calls.

  Cheers, Lars

  --
  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: help on SAWarning

2012-03-29 Thread lars van gemerden
OK, thanks, I still get the warning in some cases and i am still
zooming in on the problem for a small test case.

At least i have solved the problem of the id of InstrumentedLists
changing after commit(by bypassing one layer of recursion in the xml
tree parsing, i am not looking up the id of the IList anymore).
Cheers

On Mar 29, 4:20 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Mar 29, 2012, at 9:50 AM, lars van gemerden wrote:

  I have found that this specific behaviour (re-initialization of the
  InstrumentedList) does not happen if expire_on_commit = False is set
  on the sesssion. However this leads to other errors in my code.

  I guess I don't quite understand why expire would be called after a
  commit; shouldn't the commit result in the session being perfectly
  synchronized with the DB?

 It does.  The expire of the attributes doesn't cause any SQL to be emitted 
 until you access the attributes, in which case a new transaction is begun 
 (note the DBAPI's default mode of operation is to always be in a transaction, 
 and SQLAlchemy does not challenge this).  In between your commit() and the 
 start of a new transaction, any amount of state within the database may have 
 been changed by other transactions.

 If expire_on_commit=False is leading to errors, that would imply that this is 
 actually happening in your case.

-- 
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] return type of relationship

2012-03-29 Thread lars van gemerden
I am generating xml from SAclass objects and need to get the return
type (referred SA class)  of an relationship attribute (even if the
returned value is None). The type will be used as tagname during XML
generation.

Can anyone tell me how to get this type?

Cheers, Lars

-- 
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: names of foreign keys from unknown table/class (short question)

2012-03-27 Thread lars van gemerden
Thanks you Michael (i thought i remembered that the name attribute of
the column wasn't set unless explicitely given to the Column
constructor, the one thing i didn't check ... )



On Mar 26, 3:55 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 Column has a collection foreign_keys, a collection since a column in a 
 relational database can have any number of foreign key constraints applied to 
 it.  If this collection is non-empty, then that Column is associated with a 
 ForeignKey and thus a ForeignKeyConstraint (note that a ForeignKey is 
 ultimately an element in a larger ForeignKeyConstraint object).

 Not sure what you mean by the name - assuming you mean the name of the 
 column it refers to, ForeignKey has an accessor .column that will give you 
 the Column to which it refers to:

 http://docs.sqlalchemy.org/en/latest/core/schema.html?highlight=forei...

 That gives you the Column itself with a .name attribute.

 If by name you mean the name of the constraint itself, like for the 
 purposes of ADD CONSTRAINT/DROP CONSTRAINT, the ForeignKey object of each 
 Column is by default unnamed - in relational DDL, you don't need to give 
 explicit names to FK constraints, the database will name these automatically. 
  So unless you give them a name, the name can't be determined on the Python 
 side.  When reflecting a table, the ForeignKeyConstraint is reflected along 
 with the name, if the database supports giving us the name, and the name 
 should be associated with each associated ForeignKey object.

 On Mar 25, 2012, at 7:29 PM, lars van gemerden wrote:







  Hello,

  Does anyone know a way get the names of the foreign key columns of a
  table, if the table/class is unknown beforehand?

  I tried with Column.foreign_keys, which gives a set (why?) of
  ForeignKey objects but the name attribute of ForeignKey  is not
  automatically set.

  Cheers, Lars

  --
  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] names of foreign keys from unknown table/class (short question)

2012-03-25 Thread lars van gemerden
Hello,

Does anyone know a way get the names of the foreign key columns of a
table, if the table/class is unknown beforehand?

I tried with Column.foreign_keys, which gives a set (why?) of
ForeignKey objects but the name attribute of ForeignKey  is not
automatically set.

Cheers, Lars

-- 
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: xml approach

2012-03-23 Thread lars van gemerden
Hi Julian,

Thanks, I am looking into it and it looks interesting. Have you done much 
testing yet? How do you (plan to; haven't looked at too much detail yet) 
check for circular references (like backrefs)?

Cheers, Lars

On Thursday, March 22, 2012 11:36:41 AM UTC+1, lars van gemerden wrote:

 Hi,

 I am looking for a way to convert SQLalchemy objects to XML and back, in 
 order to support a webapplication. I made a mixin class that does a decent 
 job on 'normal' python objects (basically works for in the same cases as 
 pickle, though more testing is required). I would prefer to have a simple 
 mixin interface with something like:

 def toXML(): 
 'convert attributes to xml'
 return xmlstring

 def fromXML(xmlstring)
 'update attributes from xml'

 The most simple case would be that the web user request indicates the 
 primary key of the object, gets the corrsponding xml string in return, 
 changes fields in the xml string and posts it back, which leads to an 
 update of the object. 

 I have formulated a couple of initial questions:

 -  what attributes should be converted to and from xml?
 -  how do i handle foreign keys on the 'other' side?

 Note that the object remains in memory during the user interaction, so it 
 does not have to be reinitialized from scratch.

 Cheers, Lars

  


-- 
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/-/QNBLxpPxDBgJ.
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: short question about primary keys

2012-03-23 Thread lars van gemerden
Perfect, thank you!

On Mar 23, 10:09 pm, Benjamin Trofatter bentrofat...@gmail.com
wrote:
 Not knowing the names of the primary keys shouldn't be a problem since
 they're pretty easy to figure out with the object_mapper.

 from sqlalchemy.orm import object_mapper

 class MyMixin(object):

     def get_pk(self):
         om = object_mapper(self)
         keys = [k.key for k in om.primary_key]
         return tuple(getattr(self, k) for k in keys)

 On Fri, Mar 23, 2012 at 2:48 PM, lars van gemerden 
 l...@rational-it.comwrote:







  Hi,

  Does anyone know a way get the the value(s) of the primary key(s), if
  you don't know the name of the primary key column(s). This to be used
  in a mixin class that can be used for different tables/classes.

  Cheers, Lars

  --
  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] xml approach

2012-03-22 Thread lars van gemerden
Hi,

I am looking for a way to convert SQLalchemy objects to XML and back, in 
order to support a webapplication. I made a mixin class that does a decent 
job on 'normal' python objects (basically works for in the same cases as 
pickle, though more testing is required). I would prefer to have a simple 
mixin interface with something like:

def toXML(): 
'convert attributes to xml'
return xmlstring

def fromXML(xmlstring)
'update attributes from xml'

The most simple case would be that the web user request indicates the 
primary key of the object, gets the corrsponding xml string in return, 
changes fields in the xml string and posts it back, which leads to an 
update of the object. 

I have formulated a couple of initial questions:

-  what attributes should be converted to and from xml?
-  how do i handle foreign keys on the 'other' side?

Note that the object remains in memory during the user interaction, so it 
does not have to be reinitialized from scratch.

Cheers, Lars

 

-- 
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/-/QaC2CW65FVgJ.
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: deleting a sqlite database

2012-02-27 Thread lars van gemerden
Thank you for the extensive reply. It makes things a lot clearer;
still i am not sure about how to continue.

Conceptually i would like to create 2 sets of tables/classes in a
database (as part of a prototype):

1) one set of tables/classes with the parameters to generate other
classes/tables from,
2) one set of tables/classes that is automatically generated from the
parameters in the first set. It will feature joined inheritance with
only one root base table/class.

The only database link between these two sets is the 'polymorphic on'
column in the root base table in set 2, which is a foreign key to a
Type table in set 1.

For a typical test i would like to:

1) create records in set 1 of tables (representing classes/tables with
their attributes/foreign keys and fields),
2) from these records generate the tables/classes, where the tables
will be in set 2.
3) add records to the generated tables/classes and test whether
adding, updating, deleting and querying works as intended.

To be able to perform multiple of these tests in one run, i need to
empty the tables of set 1. However i need to completely remove any
data (mappings, class definitions, records, tables) from set 2,
between individual tests.

I (naively) thought of some ways this might be possible:

1) use two separate metadata objects for the same database, bind them
to separate 'Base' classes, one for each set  and replace the one
representing set 2 before each individual test,
2) find some way to remove all data concerning set 2 of tables from
mappings, metadata, database, etc. between tests,
3) use two databases, one for each set of tables and forego the
foreign key realtionship between then (or maybe copy set 1 to the
second database)

Please advise on which of these approaches are possible, more
straightforward, ... or whether another approach might be more
appropriate.

Cheers, Lars







On Feb 26, 10:47 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Feb 26, 2012, at 12:47 PM, lars van gemerden wrote:

  I was wrong, the method emptied the database, but I was checking the
  tables in the metadata.

  This time I am also removing the tables from the metadata, but if i
  generate the same tables in two separate test methods (with a call to
  tearDown ans setUp in between), I still get an error about a backref
  name on a relationship already existing.

 OK I think you're mixing concepts up here, a backref is an ORM concept.  The 
 Table and Metadata objects are part of Core and know absolutely nothing about 
 the ORM or mappings.    Removing a Table from a particular MetaData has 
 almost no effect as all the ORM mappings still point to it.  In reality the 
 MetaData.remove() method is mostly useless, except that a create_all() will 
 no longer hit that Table, foreign key references will no longer find it, and 
 you can replace it with a new Table object of the same name, but again 
 nothing to do with the ORM and nothing to do with the state of that removed 
 Table, which still points to that MetaData and will otherwise function 
 normally.

 If you want to remove mappings, you can call clear_mappers().  The use case 
 for removing individual mappers is not supported as there is no support for 
 doing all the reverse bookkeeping of removing relationships(), backrefs, and 
 inheritance structures, and there's really no need for such a feature.

 Like MetaData.remove(), there's almost no real world use case for 
 clear_mappers() except that of the SQLAlchemy unit tests themselves, or tests 
 of other ORM-integration layers like Elixir, which are testing the ORM itself 
 with various kinds of mappings against the same set of classes.

 Unit tests in an outside world application would normally be against a schema 
 that's an integral part of the application, and doesn't change with regards 
 to classes.   There's virtually no reason in normal applications against a 
 fixed schema to tear down mappings and table metadata between tests.    
 SQLAlchemy docs stress the Declarative pattern very much these days as we're 
 really trying to get it across that the composition of class, table metadata, 
 and mapping is best regarded as an atomic structure - it exists only as that 
 composite, or not at all.   Breaking it apart has little use unless you're 
 testing the mechanics of the mapping itself.

 Throughout all of this, we are *not* talking about the tables and schema that 
 are in the actual database.   It is typical that unit tests do drop all those 
 tables in between test suites, and recreate them for another test suite.    
 Though I tend to favor not actually dropping / recreating and instead running 
 the tests within a transaction that's rolled back at the end as it's much 
 more efficient, especially on backends like Oracle, Postgresql, MSSQL where 
 creates/drops are more expensive.   Dropping and recreating the tables in the 
 database though is independent of the structure represented by 
 Metadata/Table, though, that structure

[sqlalchemy] Re: short drop_all question

2012-02-25 Thread lars van gemerden
Actually, now I think about it, i had a couple of reasons:

- easy to start with (no separeate installation is i remember
correctly)
- no decision required about which database (mysql, postgress) to
learn
- no problem with removal of database (in memory), but that is between
runs, not during unit testing

Main reason that i want to remove the database, is that i create
tables dynamically, from another database with table definitions. To
run multiple tests I need to clear the database in between.

Lars


On Feb 24, 5:14 pm, Chris Withers ch...@simplistix.co.uk wrote:
 Why are you testing with sqlite?

 Chris

 On 24/02/2012 14:32, lars van gemerden wrote:









  OK, the file isn't closed ofcourse and i can't figure out how to close
  it. I'll try some more and if nothing works probably start a new
  post ...

  Thanks anyway, Chris

  On Feb 24, 3:02 pm, lars van gemerdenl...@rational-it.com  wrote:
  The recipe didn't work; it collects all tables, but no foreign keys
  and in the end removes nothing.

  I am using this in tearDown of unit tests. I have the DB in memory and
  even create a new engine in setUp ... maybe I am overlooking somthing
  dumb, but I don't get it.

  I'll try using a sqlite file and closing and deleting the file in
  tearDown.

  Cheers, Lars

  On Feb 24, 2:28 pm, lars van gemerdenl...@rational-it.com  wrote:

  Thanks very much,

  Nothing is ever easy ... :-(

  why not .. :-)

  On Feb 24, 2:11 pm, Chris Withersch...@simplistix.co.uk  wrote:

  On 24/02/2012 12:40, lars van gemerden wrote:

  can it be possible that drop_all does not empty the database of there
  are circular references between tables?

  You want:

 http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DropEverything

  ...which is available here too:

 http://packages.python.org/mortar_rdb/api.html#mortar_rdb.drop_tables

  cheers,

  Chris

  PS:

  I am using sqlite.

  Why? ;-)

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

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

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to 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] deleting a sqlite database

2012-02-25 Thread lars van gemerden
Hi all,

I looking for a way to delete/empty a sqlite database completely (can
be in memory or file). I have tried:

- metadata.drop_all(engine); which does not work with cyclic
references

- solution from http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DropEverything;
it requires names of foreign key columns to be returned by the
inspector class, however these names are empty

- some other ways.

I am unittesting dynamic generation of tables/classes dynamically from
definitions in another database. To be able to run multiple tests in
one run, my tearDown method must delete/empty the database.

Any tips or solutions? Have I overlooked something obvious?  It seems
that it should not be that complicated.

Cheers, Lars

-- 
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] short drop_all question

2012-02-24 Thread lars van gemerden
can it be possible that drop_all does not empty the database of there
are circular references between tables?

I am using sqlite.

Cheers, Lars

-- 
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: short drop_all question

2012-02-24 Thread lars van gemerden
Thanks very much,

Nothing is ever easy ... :-(

why not .. :-)

On Feb 24, 2:11 pm, Chris Withers ch...@simplistix.co.uk wrote:
 On 24/02/2012 12:40, lars van gemerden wrote:

  can it be possible that drop_all does not empty the database of there
  are circular references between tables?

 You want:

 http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DropEverything

 ...which is available here too:

 http://packages.python.org/mortar_rdb/api.html#mortar_rdb.drop_tables

 cheers,

 Chris

 PS:

  I am using sqlite.

 Why? ;-)

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

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to 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: short drop_all question

2012-02-24 Thread lars van gemerden
The recipe didn't work; it collects all tables, but no foreign keys
and in the end removes nothing.

I am using this in tearDown of unit tests. I have the DB in memory and
even create a new engine in setUp ... maybe I am overlooking somthing
dumb, but I don't get it.

I'll try using a sqlite file and closing and deleting the file in
tearDown.

Cheers, Lars

On Feb 24, 2:28 pm, lars van gemerden l...@rational-it.com wrote:
 Thanks very much,

 Nothing is ever easy ... :-(

 why not .. :-)

 On Feb 24, 2:11 pm, Chris Withers ch...@simplistix.co.uk wrote:







  On 24/02/2012 12:40, lars van gemerden wrote:

   can it be possible that drop_all does not empty the database of there
   are circular references between tables?

  You want:

 http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DropEverything

  ...which is available here too:

 http://packages.python.org/mortar_rdb/api.html#mortar_rdb.drop_tables

  cheers,

  Chris

  PS:

   I am using sqlite.

  Why? ;-)

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

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to 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: problem with dynamic tables/classes and inheritance

2012-02-23 Thread lars van gemerden
Seems a finally got what I wanted to achieve. Changed a lot of things,
so I cannot pinpoint the error(s) in the code above. If anyone is
interested I will help/share the solution I found.

Cheers, Lars

On Feb 22, 8:35 pm, lars van gemerden l...@rational-it.com wrote:
 I am trying to generate tables/classes dynamically. The code below is
 my latest attempt, but I cannot get it to work.

 -
  class TableName(object):
     @declared_attr
     def __tablename__(cls): return cls.__name__

 class Inherit(object):
     @declared_attr
     def id(cls): #= is not called for S
         base = cls.__bases__[len(cls.__bases__) - 1]
         print class, base:, cls.__name__, base.__name__
         return Column(Integer, ForeignKey(base.__name__ + '.id'),
 primary_key = True)
     @declared_attr
     def __mapper_args__(cls):
         return {'polymorphic_identity': cls.__name__}

 class Object(Base, TableName):

     association_tables = {}

     id = Column(Integer, primary_key = True)
     type_name = Column(String(50),  nullable = False)
     __mapper_args__ = {'polymorphic_on': type_name}

 if __name__ == '__main__':
     session = setup(engine)

     T = type('T', (Inherit, Object), {'Tdata': Column(String(50))})
     S = type('S', (T,), {'Sdata': Column(String(50))}) #= Error
     session.commit()
     print S.__table__.c
 -
 the output is:
 -
 class, base: T Object
 class, base: T Object
 class, base: T Object
 Traceback (most recent call last):
   File D:\Documents\Code\Eclipse\workspace\SQLAdata\src\test4.py,
 line 55, in module
     S = type('S', (T,), {'Sdata': Column(String(50))})
   File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py,
 line 1336, in __init__
     _as_declarative(cls, classname, cls.__dict__)
   File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py,
 line 1329, in _as_declarative
     **mapper_args)
   File C:\Python27\lib\site-packages\sqlalchemy\orm\__init__.py,
 line 1116, in mapper
     return Mapper(class_, local_table, *args, **params)
   File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line
 197, in __init__
     self._configure_inheritance()
   File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line
 473, in _configure_inheritance
     self.local_table)
   File C:\Python27\lib\site-packages\sqlalchemy\sql\util.py, line
 303, in join_condition
     between '%s' and '%s'.%s % (a.description, b.description, hint))
 sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships
 between 'T' and 'S'.
 -
 What is wrong with this approach. Is there a good way to approach this
 problem (I have tried a couple already).

 Also: Why is Inherit.id() called 3 times for T

 Please help!

 Lars

-- 
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] order of initialization __mapper_args__ 'inherit_condition' and primary key

2012-02-23 Thread lars van gemerden
Hi all,

I reproduced an error I was having with the code below (basically
pasted from the tutorial for joined inheritance) and added an
'inherit_condition' to __mapper_args__ of the subclass. At that point
the code started throwing a sqlalchemy.exc.InterfaceError. The code
is:

-

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

engine = create_engine('sqlite:///:memory:', echo=False)
Base = declarative_base(bind = engine)
Session = sessionmaker(bind = engine)


def setup(engine):
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
return Session()

class Person(Base):
__tablename__ = 'Person'
id = Column(Integer, primary_key=True)
discriminator = Column('type', String(50))
__mapper_args__ = {'polymorphic_on': discriminator}


class Engineer(Person):
__tablename__ = 'Engineer'
__mapper_args__ = {'polymorphic_identity': 'Engineer',
'inherit_condition': (id == Person.id)}
id = Column(Integer, ForeignKey('Person.id'), primary_key=True)

if __name__ == '__main__':
session = setup(engine)
e = Engineer()
session.add_all([e])
session.commit()
print e.discriminator

and the error:


Traceback (most recent call last):
  File D:\Documents\Code\Eclipse\workspace\SQLAdata\src\test5.py,
line 38, in module
print e.discriminator
  File C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py,
line 168, in __get__
return self.impl.get(instance_state(instance),dict_)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\attributes.py,
line 451, in get
value = callable_(passive)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\state.py, line
285, in __call__
self.manager.deferred_scalar_loader(self, toload)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line
1701, in _load_scalar_attributes
only_load_props=attribute_names)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\query.py, line
2378, in _load_on_ident
return q.one()
  File C:\Python27\lib\site-packages\sqlalchemy\orm\query.py, line
2050, in one
ret = list(self)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\query.py, line
2093, in __iter__
return self._execute_and_instances(context)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\query.py, line
2108, in _execute_and_instances
result = conn.execute(querycontext.statement, self._params)
  File C:\Python27\lib\site-packages\sqlalchemy\engine\base.py, line
1405, in execute
params)
  File C:\Python27\lib\site-packages\sqlalchemy\engine\base.py, line
1538, in _execute_clauseelement
compiled_sql, distilled_params
  File C:\Python27\lib\site-packages\sqlalchemy\engine\base.py, line
1646, in _execute_context
context)
  File C:\Python27\lib\site-packages\sqlalchemy\engine\base.py, line
1639, in _execute_context
context)
  File C:\Python27\lib\site-packages\sqlalchemy\engine\default.py,
line 330, in do_execute
cursor.execute(statement, parameters)
sqlalchemy.exc.InterfaceError: (InterfaceError) Error binding
parameter 0 - probably unsupported type. u'SELECT Person.type AS
Person_type, Engineer.id AS Engineer_id, Person.id AS
Person_id \nFROM Person JOIN Engineer ON Person.id = ? \nWHERE
Person.id = ?' (built-in function id, 1)
-
I fixed the error by moving the id Column in Engineer above the
__mapper_args__ :

-
class Engineer(Person):
__tablename__ = 'Engineer'
id = Column(Integer, ForeignKey('Person.id'), primary_key=True)
__mapper_args__ = {'polymorphic_identity': 'Engineer',
'inherit_condition': (id == Person.id)}
-

Now we get to the problem: In my code I dynamically generate tables
with type(name, (base,), dicty). In dicty are the __mapper_args__  and
id Column. Because of the dictionary used I have no control over the
order of the arguments and that seems to cause my exception. If I add
the __mapper_args__  with 'inherit_condition' to the class later, I
get another exception (ArgumentError: Can't determine join between
'person' and 'child'; tables have more than one foreign key constraint
relationship between them. Please specify the 'onclause' of this join
explicitly.)

Could the order in 'dicty' be the problem? Can anyone help me with a
solution or workaround for this problem.

Cheers, Lars

-- 
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: order of initialization __mapper_args__ 'inherit_condition' and primary key

2012-02-23 Thread lars van gemerden
OK, thanks, the order wasn't the problem, I am using this for the
initialization of my classes:

dicty= {'__tablename__': name,
   'id': Column(Integer, ForeignKey(basename + '.id'),
primary_key = True),
   '__mapper_args__': {'polymorphic_identity': name,
'inherit_condition': (id == classes[basename].id)}}

and as you said 'id' in the last line refers to the id() function. I
think I fixed it by changing the code to:

id_ = Column(Integer, ForeignKey(basename + '.id'), primary_key =
True)
out = {'__tablename__': name,
   'id': id_,
   '__mapper_args__': {'polymorphic_identity': name,
'inherit_condition': (id_ == classes[basename].id)}}

But I am getting a (maybe unrelated) error. Should this solution work?

Cheers, Lars


On Feb 23, 4:07 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Feb 23, 2012, at 9:56 AM, lars van gemerden wrote:









  Hi all,

  I reproduced an error I was having with the code below (basically
  pasted from the tutorial for joined inheritance) and added an
  'inherit_condition' to __mapper_args__ of the subclass. At that point
  the code started throwing a sqlalchemy.exc.InterfaceError. The code
  is:

  class Person(Base):
     __tablename__ = 'Person'
     id = Column(Integer, primary_key=True)
     discriminator = Column('type', String(50))
     __mapper_args__ = {'polymorphic_on': discriminator}

  class Engineer(Person):
     __tablename__ = 'Engineer'
     __mapper_args__ = {'polymorphic_identity': 'Engineer',
  'inherit_condition': (id == Person.id)}
     id = Column(Integer, ForeignKey('Person.id'), primary_key=True)

 Well OK, right here, when you say id, that's the Python built-in function 
 id().   This because the name id has not yet been assigned to point to 
 your new Column object.   The class Engineer(Person): is just another 
 Python block, just like an if condition: statement.   So yes, in that 
 case you need to ensure id is pointing to that Column before you stick it 
 into the inherit_condition.    This has nothing to do with the order of 
 things being looked at in the actual dict of the class, just the order of 
 how Python is assigning meaning to the name id within the class: block.

 The declarative tutorial doesn't have this bug, but yes I can see we might be 
 better off illustrating __mapper_args__ at the bottom of the class 
 declaration just to make this kind of error less likely.



  Now we get to the problem: In my code I dynamically generate tables
  with type(name, (base,), dicty). In dicty are the __mapper_args__  and
  id Column. Because of the dictionary used I have no control over the
  order of the arguments and that seems to cause my exception.

 I'm not getting how you'd have this issue there - you of course have total 
 control over what goes into a dict() to use with type(), and in what order 
 (it's only on the taking things out part of a dict that is not ordered).  
 You should generate the Column object, then you put it in the dictionary.   
 The id builtin function never gets involved:

 id = Column(...)
 dict = {
     'id':id,
    '__mapper_args__':{'inherit_condition':id==Person.id}







 }

-- 
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: order of initialization __mapper_args__ 'inherit_condition' and primary key

2012-02-23 Thread lars van gemerden
Yep, they are the same class (i don't create any class of which i
don't have the superclass yet).

Thanks for your help; on to the next bug ...

On Feb 23, 5:32 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Feb 23, 2012, at 10:47 AM, lars van gemerden wrote:









  OK, thanks, the order wasn't the problem, I am using this for the
  initialization of my classes:

     dicty= {'__tablename__': name,
            'id': Column(Integer, ForeignKey(basename + '.id'),
  primary_key = True),
            '__mapper_args__': {'polymorphic_identity': name,
  'inherit_condition': (id == classes[basename].id)}}

  and as you said 'id' in the last line refers to the id() function. I
  think I fixed it by changing the code to:

     id_ = Column(Integer, ForeignKey(basename + '.id'), primary_key =
  True)
     out = {'__tablename__': name,
            'id': id_,
            '__mapper_args__': {'polymorphic_identity': name,
  'inherit_condition': (id_ == classes[basename].id)}}

  But I am getting a (maybe unrelated) error. Should this solution work?

 that approach seems fine though classes[basename] must be already 
 established, I might pull it just from the superclass that you're passing 
 into type().

-- 
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] problem with dynamic tables/classes and inheritance

2012-02-22 Thread lars van gemerden
I am trying to generate tables/classes dynamically. The code below is
my latest attempt, but I cannot get it to work.

-
 class TableName(object):
@declared_attr
def __tablename__(cls): return cls.__name__

class Inherit(object):
@declared_attr
def id(cls): #= is not called for S
base = cls.__bases__[len(cls.__bases__) - 1]
print class, base:, cls.__name__, base.__name__
return Column(Integer, ForeignKey(base.__name__ + '.id'),
primary_key = True)
@declared_attr
def __mapper_args__(cls):
return {'polymorphic_identity': cls.__name__}

class Object(Base, TableName):

association_tables = {}

id = Column(Integer, primary_key = True)
type_name = Column(String(50),  nullable = False)
__mapper_args__ = {'polymorphic_on': type_name}



if __name__ == '__main__':
session = setup(engine)

T = type('T', (Inherit, Object), {'Tdata': Column(String(50))})
S = type('S', (T,), {'Sdata': Column(String(50))}) #= Error
session.commit()
print S.__table__.c
-
the output is:
-
class, base: T Object
class, base: T Object
class, base: T Object
Traceback (most recent call last):
  File D:\Documents\Code\Eclipse\workspace\SQLAdata\src\test4.py,
line 55, in module
S = type('S', (T,), {'Sdata': Column(String(50))})
  File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py,
line 1336, in __init__
_as_declarative(cls, classname, cls.__dict__)
  File C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py,
line 1329, in _as_declarative
**mapper_args)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\__init__.py,
line 1116, in mapper
return Mapper(class_, local_table, *args, **params)
  File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line
197, in __init__
self._configure_inheritance()
  File C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py, line
473, in _configure_inheritance
self.local_table)
  File C:\Python27\lib\site-packages\sqlalchemy\sql\util.py, line
303, in join_condition
between '%s' and '%s'.%s % (a.description, b.description, hint))
sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships
between 'T' and 'S'.
-
What is wrong with this approach. Is there a good way to approach this
problem (I have tried a couple already).

Also: Why is Inherit.id() called 3 times for T

Please help!

Lars

-- 
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] @validates clean-up

2012-02-06 Thread lars van gemerden
I am having some trouble cleaning up after my @validates method throws
an exception. The validation is of a relationship attribute and the
foreign record should be removed. Are there some general tips?
Otherwise I will post a code example.

-- 
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: Elixir question

2012-02-05 Thread lars van gemerden
OK, thank you,

I went back to SQLA and came up with this for now (simplified):

class Pairs(Base):
__tablename__ = 'Pairs'
name = Column(String(20), primary_key=True)
other_name = Column(String(20), ForeignKey('Pairs.name'), nullable
= False)

other = relationship('Pairs',
  primaryjoin = 'Pairs.name ==
Pairs.other_name',
  remote_side=[name])
def __init__(self, name):
self.name = name
def __repr__(self):
return (%s, %s) % (self.name, self.other.name)

def pair(name1, name2):
p1, p2 = Pairs(name1), Pairs(name2)
p1.other_name = name2
p2.other_name = name1
return p1, p2

if __name__ == '__main__':

p1, p2 = pair('apple', 'pear')
session.add_all([p1, p2])
session.commit()
for p in session.query(Pairs).all():
print p
assert p1.other.other is p1
--
Note that there is no backref on other and that the primaryjoin is
completely written out (otherwise a got a mysterious (to me) error,
when using joined inheritance at the same time).

This solution is key to my datamodel. Does anyone see any drawbacks?

Cheers, Lars




On Feb 5, 10:50 am, Gaëtan de Menten gdemen...@gmail.com wrote:
 On 02/03/2012 12:08 PM, lars van gemerden wrote:







  I should probably make the pair method:

  def pair(name1, name2):
       p1, p2 = Pairs(name1), Pairs(name2)
       p1.other = p2
       p2.other = p1

  On Feb 3, 11:57 am, lars van gemerdenl...@rational-it.com  wrote:
  Hi, I am trying to sote pairs in a table as follows:

  #--
   
  from elixir import *

  metadata.bind = sqlite:///:memory:
  metadata.bind.echo = False

  class Pairs(Entity):
       name = Field(String(50), primary_key = True)
       other = OneToOne('Pairs', inverse = 'other')

 You can't have a OneToOne as inverse for a OneToOne, even less for
 itself. Valid relationship pairs are:

 ManyToOne - OneToOne
 ManyToOne - OneToMany
 ManyToMany - ManyToMany

 In your case you want:

 class Pairs(Entity):
      name = Field(String(50), primary_key = True)
      other1 = ManyToOne('Pairs', inverse = 'other2')
      other2 = OneToOne('Pairs', inverse = 'other1')

 and if your database really only stores pairs, a property might make it
 more elegant:

      @property
      def other(self):
          return self.other1 if self.other1 is not None else self.other2

 As a side note, you probably do not want to use Elixir for a new
 project, as Elixir is not maintained anymore.

 -G.

-- 
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: Elixir question

2012-02-05 Thread lars van gemerden
Sorry, scrap the remark about primaryjoin ... inheritance. INheritance
wasn't the problem.

On Feb 5, 1:27 pm, lars van gemerden l...@rational-it.com wrote:
 OK, thank you,

 I went back to SQLA and came up with this for now (simplified):
 
 class Pairs(Base):
     __tablename__ = 'Pairs'
     name = Column(String(20), primary_key=True)
     other_name = Column(String(20), ForeignKey('Pairs.name'), nullable
 = False)

     other = relationship('Pairs',
                           primaryjoin = 'Pairs.name ==
 Pairs.other_name',
                           remote_side=[name])
     def __init__(self, name):
         self.name = name
     def __repr__(self):
         return (%s, %s) % (self.name, self.other.name)

 def pair(name1, name2):
     p1, p2 = Pairs(name1), Pairs(name2)
     p1.other_name = name2
     p2.other_name = name1
     return p1, p2

 if __name__ == '__main__':

     p1, p2 = pair('apple', 'pear')
     session.add_all([p1, p2])
     session.commit()
     for p in session.query(Pairs).all():
         print p
     assert p1.other.other is p1
 --
 Note that there is no backref on other and that the primaryjoin is
 completely written out (otherwise a got a mysterious (to me) error,
 when using joined inheritance at the same time).

 This solution is key to my datamodel. Does anyone see any drawbacks?

 Cheers, Lars

 On Feb 5, 10:50 am, Gaëtan de Menten gdemen...@gmail.com wrote:







  On 02/03/2012 12:08 PM, lars van gemerden wrote:

   I should probably make the pair method:

   def pair(name1, name2):
        p1, p2 = Pairs(name1), Pairs(name2)
        p1.other = p2
        p2.other = p1

   On Feb 3, 11:57 am, lars van gemerdenl...@rational-it.com  wrote:
   Hi, I am trying to sote pairs in a table as follows:

   #--

   from elixir import *

   metadata.bind = sqlite:///:memory:
   metadata.bind.echo = False

   class Pairs(Entity):
        name = Field(String(50), primary_key = True)
        other = OneToOne('Pairs', inverse = 'other')

  You can't have a OneToOne as inverse for a OneToOne, even less for
  itself. Valid relationship pairs are:

  ManyToOne - OneToOne
  ManyToOne - OneToMany
  ManyToMany - ManyToMany

  In your case you want:

  class Pairs(Entity):
       name = Field(String(50), primary_key = True)
       other1 = ManyToOne('Pairs', inverse = 'other2')
       other2 = OneToOne('Pairs', inverse = 'other1')

  and if your database really only stores pairs, a property might make it
  more elegant:

       @property
       def other(self):
           return self.other1 if self.other1 is not None else self.other2

  As a side note, you probably do not want to use Elixir for a new
  project, as Elixir is not maintained anymore.

  -G.

-- 
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] Elixir question

2012-02-03 Thread lars van gemerden
Hi, I am trying to sote pairs in a table as follows:

#--
from elixir import *

metadata.bind = sqlite:///:memory:
metadata.bind.echo = False

class Pairs(Entity):
name = Field(String(50), primary_key = True)
other = OneToOne('Pairs', inverse = 'other')

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

def pair(name1, name2):
p1, p2 = Pairs(name1), Pairs(name2)
p1.other = p2

if __name__ == '__main__':

setup_all()
create_all()

pair('p1', 'p2')
#--

I am not very famiiar with SQL etc. but logically this seems possible
(please orrect me if I am wrong). However I get the following error:

File D:\Documents\Code\Eclipse\workspace\SQLAdata\src\tests.py, line
22, in module
setup_all()
  File build\bdist.win-amd64\egg\elixir\__init__.py, line 94, in
setup_all

  File build\bdist.win-amd64\egg\elixir\entity.py, line 951, in
setup_entities
  File build\bdist.win-amd64\egg\elixir\entity.py, line 198, in
create_pk_cols
  File build\bdist.win-amd64\egg\elixir\entity.py, line 481, in
call_builders
  File build\bdist.win-amd64\egg\elixir\relationships.py, line 448,
in create_pk_cols
  File build\bdist.win-amd64\egg\elixir\relationships.py, line 791,
in create_keys
  File build\bdist.win-amd64\egg\elixir\relationships.py, line 521,
in inverse
AssertionError: Relationships 'other' in entity 'Pair' and 'other' in
entity 'Pair' cannot be inverse of each other because their types do
not form a valid combination.


Can anyone help me to understand the error and possibly fix it?

Thanks in advance, Lars

-- 
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: Elixir question

2012-02-03 Thread lars van gemerden
I should probably make the pair method:

def pair(name1, name2):
p1, p2 = Pairs(name1), Pairs(name2)
p1.other = p2
p2.other = p1

On Feb 3, 11:57 am, lars van gemerden l...@rational-it.com wrote:
 Hi, I am trying to sote pairs in a table as follows:

 #-- 
 
 from elixir import *

 metadata.bind = sqlite:///:memory:
 metadata.bind.echo = False

 class Pairs(Entity):
     name = Field(String(50), primary_key = True)
     other = OneToOne('Pairs', inverse = 'other')

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

 def pair(name1, name2):
     p1, p2 = Pairs(name1), Pairs(name2)
     p1.other = p2

 if __name__ == '__main__':

     setup_all()
     create_all()

     pair('p1', 'p2')
 #-- 
 

 I am not very famiiar with SQL etc. but logically this seems possible
 (please orrect me if I am wrong). However I get the following error:
 
 File D:\Documents\Code\Eclipse\workspace\SQLAdata\src\tests.py, line
 22, in module
     setup_all()
   File build\bdist.win-amd64\egg\elixir\__init__.py, line 94, in
 setup_all

   File build\bdist.win-amd64\egg\elixir\entity.py, line 951, in
 setup_entities
   File build\bdist.win-amd64\egg\elixir\entity.py, line 198, in
 create_pk_cols
   File build\bdist.win-amd64\egg\elixir\entity.py, line 481, in
 call_builders
   File build\bdist.win-amd64\egg\elixir\relationships.py, line 448,
 in create_pk_cols
   File build\bdist.win-amd64\egg\elixir\relationships.py, line 791,
 in create_keys
   File build\bdist.win-amd64\egg\elixir\relationships.py, line 521,
 in inverse
 AssertionError: Relationships 'other' in entity 'Pair' and 'other' in
 entity 'Pair' cannot be inverse of each other because their types do
 not form a valid combination.
 

 Can anyone help me to understand the error and possibly fix it?

 Thanks in advance, Lars

-- 
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] a more general elixir question

2012-02-03 Thread lars van gemerden
Is it possible to mix Elixir classes and SQLA classes in one database
(with foreign keys between them)?

Cheers, Lars

-- 
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: a more general elixir question

2012-02-03 Thread lars van gemerden
Thanks,

Can you also mix Elixir Fields and SQLA Column/relationships in the
same class?

Cheers, Lars

On Feb 3, 12:56 pm, erikj tw55...@gmail.com wrote:
 yes

 Elixir classes are in fact SQLA classes, only defined with
 a different syntax

 you can mix Elixir, Declarative and plain python objects mapped
 with SQLA

 On Feb 3, 12:13 pm, lars van gemerden l...@rational-it.com wrote:







  Is it possible to mix Elixir classes and SQLA classes in one database
  (with foreign keys between them)?

  Cheers, Lars

-- 
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: a more general elixir question

2012-02-03 Thread lars van gemerden
Too bad, thanks

On Feb 3, 1:38 pm, erikj tw55...@gmail.com wrote:
 no, that's not possible

 Elixir does some custom postprocessing on a class
 definition, and so does Declarative, but they are not
 interoperatable

 On Feb 3, 1:20 pm, lars van gemerden l...@rational-it.com wrote:







  Thanks,

  Can you also mix Elixir Fields and SQLA Column/relationships in the
  same class?

  Cheers, Lars

  On Feb 3, 12:56 pm, erikj tw55...@gmail.com wrote:

   yes

   Elixir classes are in fact SQLA classes, only defined with
   a different syntax

   you can mix Elixir, Declarative and plain python objects mapped
   with SQLA

   On Feb 3, 12:13 pm, lars van gemerden l...@rational-it.com wrote:

Is it possible to mix Elixir classes and SQLA classes in one database
(with foreign keys between them)?

Cheers, Lars

-- 
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: multiple inheritance experiment

2011-04-21 Thread Lars
Thank you,

In the last suggestion:

@property
def users_and_orders(self):
return self.users + self.orders

or to simulate a polymorphic union, do
object_session(self).query().union(object_session(self).query())
etc.

Do you have any suggestions to make the result have an append/remove
method which persists to the database?

Perhaps with a descriptor or custom collection type?

Cheers, Lars





On Apr 15, 6:49 am, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 13, 2011, at 5:52 AM, Lars wrote:

  Hi Michael,

  I am trying to figure out the two suggestions you did, and not getting
  very far. Some basic questions:

  - if A, B, C are mapped classes, can you do A.join(B, A.id ==
  B.id).join(C, B.id == C.id).join(   ?

 usually if you want to use join() you'd deal with tables, like 
 table_a.join(table_b, ...).join(...).   though the orm.join() function will 
 receive classes directly, its 
 inhttp://www.sqlalchemy.org/docs/orm/tutorial.html#querying-with-joins

  - Would using join in such a way make access to mapped attributes in
  one of the joined tables excessively slow?

 joins are slower than straight single table selects especially in MySQL, if 
 thats the question

  - What is the difference between using association_proxy and
  relationship(... secondary = .., ..., secondaryjoin = ...)?

 three concepts.  one is 
 many-to-many:http://www.sqlalchemy.org/docs/orm/relationships.html#many-to-many next
  is the association pattern, a many to many where extra data is linked with 
 each 
 association:http://www.sqlalchemy.org/docs/orm/relationships.html#association-object next
  is association proxy, when you've worked with an association for awhile and 
 are tired of saying parent.association.child and want to just skip the 
 .association part in the usual case

  - in the example in poly_assoc_generic.py, is there a way to define an
  attribute on address that returns a list with both orders and
  users with that address (and be able to append that list) ?

 these collections load from entirely different tables.  Usually you'd need to 
 do it manually:

 @property
 def users_and_orders(self):
     return self.users + self.orders

 or to simulate a polymorphic union, do 
 object_session(self).query().union(object_session(self).query()) etc.

-- 
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] short question on Table

2011-04-16 Thread Lars
Hi all,

Does anyone know how I can add a Column to an existing not yet mapped
Table?

Cheers, Lars

-- 
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] short question on Table

2011-04-16 Thread Lars
Hi all,

Does anyone know how I can add a Column to an existing not yet mapped
Table?

Cheers, Lars

-- 
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: multiple inheritance experiment

2011-04-13 Thread Lars
Hi Michael,

I am trying to figure out the two suggestions you did, and not getting
very far. Some basic questions:

- if A, B, C are mapped classes, can you do A.join(B, A.id ==
B.id).join(C, B.id == C.id).join(   ?
- Would using join in such a way make access to mapped attributes in
one of the joined tables excessively slow?
- What is the difference between using association_proxy and
relationship(... secondary = .., ..., secondaryjoin = ...)?
- in the example in poly_assoc_generic.py, is there a way to define an
attribute on address that returns a list with both orders and
users with that address (and be able to append that list) ?

Please help, Lars



On Apr 11, 8:45 pm, Lars gemer...@gmail.com wrote:
 Hi again,

 On Apr 10, 11:17 pm, Michael Bayer mike...@zzzcomputing.com wrote: On Apr 
 10, 2011, at 1:27 PM, Lars wrote:

   Hi Michael,

   Thank you for the suggestions.

   I noticed that all the foreign keys to superclasses are identical
   (same id number). What would be the disadvantage of using only primary
   keys and using those in setting up relationships (compared to using
   foreign keys)?

  When two columns in a relational database, one being a primary key, the 
  other being possibly a primary key, are logically constrained to have the 
  same value, that's known as a foreign key.  It's then best practice to 
  actually place a real foreign key constraint in the database to enforce 
  this at the data level.   SQLite and MySQL by default don't enforce it, 
  though.   SQLAlchemy doesn't particularly care if an actual constraint is 
  defined in the database, it can be told to join on any combination of 
  columns.   The presence of a foreign key within table metadata just makes 
  this automatic.

 Does that mean that if you don't set the foreign key constraint and
 you want to be able to set an attribute, you also have to write code
 to copy the primary key of the parent to the child?

   If I use a root base class (similar to object in python) and add a
   type column/attribute to refer to the actual class of the object/
   record, is there an elegant way to get/set/del the polymorphic
   attribute object of the correct class using this type?

  Which table is this type column present in, base1 or base2 ?  

 Neither, I was thinking of using a class that is the root base class
 of all classes (not present in code above) to store the type and the
 primary key of all objects. This type should be accessible in all
 classes, since they would all be direct or indirect subclasses of this
 root class. Say that I store all classes in a dictionary called
 registry, then registry[type] would give the actual class of the
 object identified with the primary key in the root class table. This
 key would also identify the correct record in all superclasses of this
 class, e.g. to be used in a join over these classes.

 (hope this is somewhat clear ...)



   Would it be possible to redefine query() using this type to first
   resolve the correct table and use the query method SA provides on that
   (without this resulting in otherwise changing the API) ?

  but what's the correct table, base1, base2, claz ?    with multiple 
  inheritance the path is not a straight line.  If you have a mostly straight 
  inheritance model with an occasional offshoot, say its base1 - subbase1 - 
  (subbase1 , base2) - claz, I'd use traditional inheritance and have just 
  base2 via relationship().  

 The correct table would be the table corresponding to the value in the
 type column. I am working on a framework where others will design the
 data structure and would like to use a uniform metadata model to avoid
 extra choices for the designer.



 Cheers again, Lars









   On Apr 7, 8:42 pm, Michael Bayer mike...@zzzcomputing.com wrote:
   On Apr 7, 2011, at 2:30 PM, Lars wrote:

   Hello,

   I am pretty determined to find a way to get (a simplified version of)
   multiple inheritance working with SA. The simplification lies in that
   no overriding of attributes will be possible (but I don't know whether
   that is significant). I was thinking of a schema as follows:

   ---
---

   metadata = MetaData()

   base1_table = Table(base1_table, metadata,
      Column('id', Integer, primary_key=True),
      Column('str', String)
      )

   base2_table = Table(base2_table, metadata,
      Column('id', Integer, primary_key=True),
      Column('int', Integer)
      )

   claz1_table = Table(claz1_table, metadata,
      Column('id', Integer, primary_key=True),
      Column('base1_id', None, ForeignKey('base1_table.id')),
      Column('base2_id', None, ForeignKey('base2_table.id')),
      Column('assoc_id', None, ForeignKey('assoc_table.id'))
      )

   assoc_table = Table(assoc_table, metadata,
      Column('id', Integer, primary_key=True),
      Column('name', String(50), nullable=False),
      Column('type', String(50), nullable

[sqlalchemy] Re: Avoiding spaghetti inheritance

2011-04-13 Thread Lars
Hi Luca,

There are a couple of things you could try:

1) Analyse the business logic further to figure out what fields
structurally necessary for different types of product and/or important
for queries, decide how far you want to take the inheritance tree from
there.
2) Fields that are likely to change you could combine and store in a
text field (e.g. in XML) and parse in your python application, some
queries are still possible by searching the text (SQL: ..LIKE.. I
think).
3) Use a one to many attribute properties (or some such) .. I guess
that is the tags approach .. with a properties table having a foreign
key to the product/service table, a property name and a property value
(probably text, so if it would have to represent an e.g. an integer,
querying for e.g.  would be a problem).

I think it is a well known problem, especially for companies with many
different products, like an electronics web shop, where customers want
to search for products with specific properties. Having a separate
table for each type of product is a pain, especially if new types come
out rapidly (tv, lcd, plasma, 3D TV), thats why you often get choices
for e.g. screensize instead of being able to set  36 . I guess they
use option 3 or maybe 2.

Hope this helps,

Lars


On Apr 7, 10:36 pm, Luca Lesinigo l...@lesinigo.it wrote:
 Hello there. I'm using SA-0.7 to develop an application that should
 help me manage my company's services.

 A central concept here is the order, it could be a service (like one
 year of web hosting) or a physical item (like a pc we sell). So far I
 generalized them in two classes: the Order and the ServiceOrder - the
 latter simply inherits the former and adds start and end dates.

 Now I need to add all various kinds of metadata to orders, for
 example:
 - a ServiceOrder for a domain hosting should contain the domain name
 - a ServiceOrder for a maintenance service should contain the service
 level for that service (say, basic or advanced)
 - an Order for a PC we delivered should contain its serial number
 - and so on...

 I could easily add child classes, but that would mean to keep and
 maintain that code forever even after we stop using it (ie, next year
 we stop doing hosting) or when it's not really useful (many things
 will just have some 'metadata' in them like a serial number or similar
 things). I'd also like to avoid having to add code every time we just
 hit something slightly different to manage, when we just have some
 additional data to keep track of.
 I wonder what could be an intelligent approach to such a situation.

 One idea I got could be to add an 'OrderTags' table / class that would
 associate (tag, value) tuples to my orders, and somehow access them
 like a dictionary (eg. Order.tags['serialnumber'] = 'foo' or
 ServiceOrder.tags['domainname'] = 'example.com'). But that will
 probably keep them out of standard SA queries? For example, if I want
 to retrieve the full history of a domain we're hosting, how could I
 query for all orders with (tags['domainname'] == something)?

 I'm looking for advice on how to structure this data, and how to best
 implement it with python and sqlalchemy-0.7.

 Thank you,
 Luca

-- 
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: multiple inheritance experiment

2011-04-11 Thread Lars
Hi again,

On Apr 10, 11:17 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 10, 2011, at 1:27 PM, Lars wrote:

  Hi Michael,

  Thank you for the suggestions.

  I noticed that all the foreign keys to superclasses are identical
  (same id number). What would be the disadvantage of using only primary
  keys and using those in setting up relationships (compared to using
  foreign keys)?

 When two columns in a relational database, one being a primary key, the other 
 being possibly a primary key, are logically constrained to have the same 
 value, that's known as a foreign key.  It's then best practice to actually 
 place a real foreign key constraint in the database to enforce this at the 
 data level.   SQLite and MySQL by default don't enforce it, though.   
 SQLAlchemy doesn't particularly care if an actual constraint is defined in 
 the database, it can be told to join on any combination of columns.   The 
 presence of a foreign key within table metadata just makes this automatic.

Does that mean that if you don't set the foreign key constraint and
you want to be able to set an attribute, you also have to write code
to copy the primary key of the parent to the child?

  If I use a root base class (similar to object in python) and add a
  type column/attribute to refer to the actual class of the object/
  record, is there an elegant way to get/set/del the polymorphic
  attribute object of the correct class using this type?

 Which table is this type column present in, base1 or base2 ?  

Neither, I was thinking of using a class that is the root base class
of all classes (not present in code above) to store the type and the
primary key of all objects. This type should be accessible in all
classes, since they would all be direct or indirect subclasses of this
root class. Say that I store all classes in a dictionary called
registry, then registry[type] would give the actual class of the
object identified with the primary key in the root class table. This
key would also identify the correct record in all superclasses of this
class, e.g. to be used in a join over these classes.

(hope this is somewhat clear ...)


  Would it be possible to redefine query() using this type to first
  resolve the correct table and use the query method SA provides on that
  (without this resulting in otherwise changing the API) ?

 but what's the correct table, base1, base2, claz ?    with multiple 
 inheritance the path is not a straight line.  If you have a mostly straight 
 inheritance model with an occasional offshoot, say its base1 - subbase1 - 
 (subbase1 , base2) - claz, I'd use traditional inheritance and have just 
 base2 via relationship().  

The correct table would be the table corresponding to the value in the
type column. I am working on a framework where others will design the
data structure and would like to use a uniform metadata model to avoid
extra choices for the designer.


Cheers again, Lars





  On Apr 7, 8:42 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  On Apr 7, 2011, at 2:30 PM, Lars wrote:

  Hello,

  I am pretty determined to find a way to get (a simplified version of)
  multiple inheritance working with SA. The simplification lies in that
  no overriding of attributes will be possible (but I don't know whether
  that is significant). I was thinking of a schema as follows:

  ---
   ---

  metadata = MetaData()

  base1_table = Table(base1_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('str', String)
     )

  base2_table = Table(base2_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('int', Integer)
     )

  claz1_table = Table(claz1_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('base1_id', None, ForeignKey('base1_table.id')),
     Column('base2_id', None, ForeignKey('base2_table.id')),
     Column('assoc_id', None, ForeignKey('assoc_table.id'))
     )

  assoc_table = Table(assoc_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('name', String(50), nullable=False),
     Column('type', String(50), nullable=False)
  )

  base3_table = Table(base3_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('assoc_id', None, ForeignKey('assoc_table.id')),
     Column('bool', Boolean)
     )

  claz2_table = Table(claz2_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('base3_id', None, ForeignKey('base3_table.id')),
     Column('date', Date)
     )

  class base1(object):
     pass
  class base2(object):
     pass
  class base3(object):
     pass
  class claz1(base1, base2):
     pass
  class claz2(base3):
     pass

  # do mappings, relationships and e.g. be able to

  c1 = claz1(str = hello, int = 17)
  setattr(c1, name, claz2(bool = True, date = Date(2010,9,10)))

  You can just forego the inherits flag and map each class to the 
  appropriate join or base

[sqlalchemy] Re: multiple inheritance experiment

2011-04-10 Thread Lars
Hi Michael,

Thank you for the suggestions.

I noticed that all the foreign keys to superclasses are identical
(same id number). What would be the disadvantage of using only primary
keys and using those in setting up relationships (compared to using
foreign keys)?

If I use a root base class (similar to object in python) and add a
type column/attribute to refer to the actual class of the object/
record, is there an elegant way to get/set/del the polymorphic
attribute object of the correct class using this type? Would that be
possible with the first option you described above?

Would it be possible to redefine query() using this type to first
resolve the correct table and use the query method SA provides on that
(without this resulting in otherwise changing the API) ?

Cheers, Lars


On Apr 7, 8:42 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 7, 2011, at 2:30 PM, Lars wrote:









  Hello,

  I am pretty determined to find a way to get (a simplified version of)
  multiple inheritance working with SA. The simplification lies in that
  no overriding of attributes will be possible (but I don't know whether
  that is significant). I was thinking of a schema as follows:

  --- 
  ---

  metadata = MetaData()

  base1_table = Table(base1_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('str', String)
     )

  base2_table = Table(base2_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('int', Integer)
     )

  claz1_table = Table(claz1_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('base1_id', None, ForeignKey('base1_table.id')),
     Column('base2_id', None, ForeignKey('base2_table.id')),
     Column('assoc_id', None, ForeignKey('assoc_table.id'))
     )

  assoc_table = Table(assoc_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('name', String(50), nullable=False),
     Column('type', String(50), nullable=False)
  )

  base3_table = Table(base3_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('assoc_id', None, ForeignKey('assoc_table.id')),
     Column('bool', Boolean)
     )

  claz2_table = Table(claz2_table, metadata,
     Column('id', Integer, primary_key=True),
     Column('base3_id', None, ForeignKey('base3_table.id')),
     Column('date', Date)
     )

  class base1(object):
     pass
  class base2(object):
     pass
  class base3(object):
     pass
  class claz1(base1, base2):
     pass
  class claz2(base3):
     pass

  # do mappings, relationships and e.g. be able to

  c1 = claz1(str = hello, int = 17)
  setattr(c1, name, claz2(bool = True, date = Date(2010,9,10)))

 You can just forego the inherits flag and map each class to the appropriate 
 join or base table.   claz1 would be mapped to a join of the three tables 
 involved.    The difficult part of course is the query side, if you're 
 looking to query base1 or base2 and get back claz1 objects.    

 Alternatively, each class can be mapped to one table only, and relationship() 
 used to link to other tables.     Again if you don't use the inherits flag, 
 you can maintain the class hierarchy on the Python side and use association 
 proxies to provide local access to attributes that are normally on the 
 related class.   This would still not give you polymorphic loading but would 
 grant a little more flexibility in which tables are queried to start.









  --- 
  --

  I am still pretty new to SA. Can anyone give me any hints, tips,
  issues with this scheme (e.g. about how to do the mappings,
  descriptors, etc)?

  The step after will be to write factory functions/metaclasses to
  generate these dynamically.

  Multiple inheritance is very important for my use case.

  Cheers, Lars

  --
  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: when is object.id initialized

2011-04-07 Thread Lars
OK, thanks, this was part of the ActiveRecord kind of approach I was
playing with, which after reading your article at zzzeek and the
alternative described there I will probably shelve.

On Apr 6, 9:59 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 6, 2011, at 6:38 AM, farcat wrote:

  Thank you,

  I now experiment with putting  session.add and session.flush in
  object.__init__ ..

  Are there any general disadvantages of that approach?

 Using add() inside of __init__ is somewhat common.   Using flush() has the 
 significant downside that flushes occur too often which is wasteful and 
 performs poorly for larger scale operations (like bulk loads and such).   The 
 ORM is designed such that primary key identifiers are not needed to be 
 explicitly accessed outside of a flush except for query situations that wish 
 to avoid the usage of relationships.   When you build your application to be 
 strongly dependent on primary key identifiers being available within 
 otherwise fully pending object graphs, you begin to work against the usage 
 goals of the ORM.









  On Apr 3, 7:44 pm, Michael Bayer mike...@zzzcomputing.com wrote:
  Integer primary key identifiers are generated by the database itself using 
  a variety of techniques which are all database-dependent.  This process 
  occurs when the session flushes.

  If you read the object relational tutorial starting 
  athttp://www.sqlalchemy.org/docs/orm/tutorial.html#setting-up-the-mappi...working
   down through the end 
  ofhttp://www.sqlalchemy.org/docs/orm/tutorial.html#adding-new-objectsyouwill
   see that this interaction is described.

  You can of course set .id to any value you'd like and that will be the 
  value used when the flush happens.

  On Apr 3, 2011, at 1:09 PM, farcat wrote:

  Hi all,

  I use a kind of dynamic reference from parent_table to other tables.
  For that parent_table uses columns table_name and a record_id. This
  makes it possible to have a reference from parent_table to any record
  in any table in the database. However, say that i want to reference a
  record of table_name, i need the record.id to initialize
  parent_table.record_id. However, when i create a record and
  session.add it to the database, record.id == None.

  I was wondering when and how record.id is initialized and how it can
  be forced.

  Cheers, Lars

  --
  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 
  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: how to delete record (special case)

2011-04-07 Thread Lars
Hi Michael,

I am trying to run the alternative you described in the article, but
the following code is most likely from an old version of SA a don't
know how to update (I am working with 6.6):

mapper = class_mapper(cls)
table = mapper.local_table
mapper.add_property(attr_name, relationship(GenericAssoc,
backref=backref('_backref_%s' % table.name, uselist=False)))

class_mapper is unknown or moved.

What does it do/how can I fix this?

Cheers, Lars

On Apr 6, 10:18 pm, Michael Bayer mike...@zzzcomputing.com wrote:
 On Apr 6, 2011, at 5:43 AM, farcat wrote:

  Hello,

  I am experimenting with a pattern where records hold the table name
  and record id of the next record in any other table, chaining records
  in different tables. This works, but I can't figure out how to clean
  op references to the next record in another table when I delete a
  record (the pattern does not use foreign keys in the normal sense).

 .. in that it doesn't use foreign keys.    Since you're working against the 
 relational database's supported patterns, you'd need to roll the deletion of 
 related rows yourself.    The pattern is also called a polymorphic 
 association and I blogged about it years ago here:  
 http://techspot.zzzeek.org/2007/05/29/polymorphic-associations-with-s







  The code is:

  =

  from sqlalchemy import *
  from sqlalchemy.orm.session import sessionmaker
  from sqlalchemy.ext.declarative import declarative_base,
  declared_attr, DeclarativeMeta
  #-- 
  -
  Base = declarative_base()
  reg = dict()
  engine = create_engine('sqlite:///:memory:', echo=False)
  Session = sessionmaker(bind = engine)
  #-- 
  -

  class chainmeta(DeclarativeMeta):
  #-- 
  -
     class Base(object):
         session = Session()
         @declared_attr
         def __tablename__(cls):
             return cls.__name__

         id = Column(Integer, primary_key = True)
         next_table = Column(String(64))
         next_id = Column(Integer) #in table with name stored in
  next_table!

         def __init__(self, data, next = None):
             self.data = data
             self.prev = None
             self.next = next
             self.session.add(self)
             self.session.flush()

         def _getnext(self):
             if self.next_table and self.next_id:

                 return
  self.session.query(reg[self.next_table]).filter(self.next_id ==
  reg[self.next_table].id).one()
             else: return None

         def _setnext(self, next):
             if next:
                 if self.next:
                     self.next.prev = None
                 self.next_table = next.__tablename__
                 self.next_id = next.id
                 next.prev = self
             elif self.next:
                 self.next.prev = None
                 self.next_table = None
                 self.next_id = None

         def _delnext(self):
             self.next.prev = None
             self.next_table = None
             self.next_id = None

         next = property(_getnext, _setnext, _delnext)

         def __repr__(self):
             out = type:  + type(self).__name__ + [
             for name in self.__dict__:
                 out += name + , 
             out += ]
             return out
  #-- 
  -
     def __new__(mcls, name, coltype):
         return DeclarativeMeta.__new__(mcls, name, (chainmeta.Base,
  Base),{data: Column(coltype, nullable = False)})
     def __init__(cls, name, coltype):
         reg[name] = cls
         return DeclarativeMeta.__init__(cls, name, (chainmeta.Base,
  Base),{})
  #-- 
  -
  if __name__ == '__main__':
     Base.metadata.drop_all(engine)
     session = chainmeta.Base.session = Session()

     Ni = chainmeta(Ni, Integer)
     Nb = chainmeta(Nb, Boolean)
     Nt = chainmeta(Nt, String(200))
     Base.metadata.create_all(engine)

     ni1 = Ni(5)
     ni2 = Ni(12)
     nb1 = Nb(True)
     nb2 = Nb(False)
     nt1 = Nt(text in nt1)
     nt2 = Nt(text in nt2)
     ni1.next = ni2
     ni2.next = nb1
     nb1.next = nb2
     nb2.next = nt1
     nt1.next = nt2
     nt2.next = ni1 #circular
     print OBJECTS
     n = ni1
     count = 0
     print nexts: .
     while n and count  10:
         print n.data
         count += 1
         n = n.next
     n = ni1
     count = 0
     print prevs: .
     while n and count  10:
         print n.data
         count += 1
         n = n.prev
     print
  -- 
  -
     nts = session.query(Nt).all()
     print QUERIES

  1   2   >