[sqlalchemy] Dangers of setting a session's expire_on_commit=False?

2014-07-25 Thread Paul Molodowitch
Hi all - so I'm thinking of disabling the expire_on_commit property for my
default sessionmaker object, and I was wondering what the potential issues
with this were.  Is it simply that the next access of the data on it could
be using out-of-date information?  Don't objects potentially have this
problem anyway, in the sense that if they are accessed TWICE after a
commit, the second access will use the data cached from the first, and
could again be out of date?

To give some background - we're in the middle of converting an existing
codebase to use sqlalchemy, and there are number of classes that act both
as database wrappers, AND "data structures."  That is, when first
constructed, they are populated with data from the database; but from then
on out, they just keep the cached data.  So they would behave similarly to
ORM-mapped objects, if expire_on_commit is False.  The thinking here is
that for most of these classes, the data changes fairly infrequently, and
it's not catastrophic if it's somewhat out of date. Also we don't want to
keep hitting the database more than necessary...  and, finally, we might
need to have access to the cached data for a long time (ie, as long as the
user has a ui window open).

-- 
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] problems with mysql reflect

2014-07-11 Thread Paul Molodowitch
oops, that line should read "Python 2.6 doesn't accept", not "except".

My hands are too used to typing "except SomeError:"...


On Fri, Jul 11, 2014 at 11:38 AM, Paul Molodowitch 
wrote:

> Done:
>
>
> https://bitbucket.org/zzzeek/sqlalchemy/issue/3123/mysql-reflection-on-python-26-causes-error
>
> FYI, for now we're patching sqlalchemy/engine/reflection.py, changing
> Inspector.reflectable after it gets tbl_opts (line 450 in my code):
>
> # reflect table options, like mysql_engine
> tbl_opts = self.get_table_options(table_name, schema,
> **table.dialect_kwargs)
> # Python 2.6 doesn't except using dicts with unicode keys for
> kwargs,
> # ie, myFunc(**{u'foo':1}) will raise an error
> if sys.version_info < (2, 7):
> for key, val in tbl_opts.items():
> if isinstance(key, unicode):
> del tbl_opts[key]
> tbl_opts[str(key)] = val
>
> There's likely a much better / more elegant way to handle this, but it
> seems to do the trick for us...
>
> Let me know anything's not clear, or you're having troubles replicating,
> or there's anything else I can do to help!
>
> - Paul
>
>
> On Thu, Jul 10, 2014 at 6:06 PM, Mike Bayer 
> wrote:
>
>>
>> On 7/10/14, 3:49 PM, Paul Molodowitch wrote:
>>
>> Whoops! Just noticed this was the totally wrong traceback!
>>
>>  Here's the correct trace:
>>
>>   Traceback (most recent call last):
>>   File "", line 1, in 
>>   File "test.py", line 155, in 
>> metadata.reflect(db.engine, only=tables)
>>   File "./sqlalchemy/sql/schema.py", line 3277, in reflect
>>  Table(name, self, **reflect_opts)
>>   File "./sqlalchemy/sql/schema.py", line 352, in __new__
>> table._init(name, metadata, *args, **kw)
>>   File "./sqlalchemy/sql/schema.py", line 425, in _init
>> self._autoload(metadata, autoload_with, include_columns)
>>   File "./sqlalchemy/sql/schema.py", line 437, in _autoload
>> self, include_columns, exclude_columns
>>File "./sqlalchemy/engine/base.py", line 1198, in run_callable
>> return callable_(self, *args, **kwargs)
>>File "./sqlalchemy/engine/default.py", line 355, in reflecttable
>> return insp.reflecttable(table, include_columns, exclude_columns)
>>   File "./sqlalchemy/engine/reflection.py", line 463, in reflecttable
>> for col_d in self.get_columns(table_name, schema,
>> **table.dialect_kwargs):
>> TypeError: get_columns() keywords must be strings
>>
>>
>> with metadata.reflect(), OK.  Can you please make a very short and
>> self-contained test case and post a bug report?  thanks.
>>
>>
>>  --
>> 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/E3MhX1m8QqQ/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/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.


Re: [sqlalchemy] problems with mysql reflect

2014-07-11 Thread Paul Molodowitch
Done:

https://bitbucket.org/zzzeek/sqlalchemy/issue/3123/mysql-reflection-on-python-26-causes-error

FYI, for now we're patching sqlalchemy/engine/reflection.py, changing
Inspector.reflectable after it gets tbl_opts (line 450 in my code):

# reflect table options, like mysql_engine
tbl_opts = self.get_table_options(table_name, schema,
**table.dialect_kwargs)
# Python 2.6 doesn't except using dicts with unicode keys for
kwargs,
# ie, myFunc(**{u'foo':1}) will raise an error
if sys.version_info < (2, 7):
for key, val in tbl_opts.items():
if isinstance(key, unicode):
del tbl_opts[key]
tbl_opts[str(key)] = val

There's likely a much better / more elegant way to handle this, but it
seems to do the trick for us...

Let me know anything's not clear, or you're having troubles replicating, or
there's anything else I can do to help!

- Paul


On Thu, Jul 10, 2014 at 6:06 PM, Mike Bayer 
wrote:

>
> On 7/10/14, 3:49 PM, Paul Molodowitch wrote:
>
> Whoops! Just noticed this was the totally wrong traceback!
>
>  Here's the correct trace:
>
>   Traceback (most recent call last):
>   File "", line 1, in 
>   File "test.py", line 155, in 
> metadata.reflect(db.engine, only=tables)
>   File "./sqlalchemy/sql/schema.py", line 3277, in reflect
>  Table(name, self, **reflect_opts)
>   File "./sqlalchemy/sql/schema.py", line 352, in __new__
> table._init(name, metadata, *args, **kw)
>   File "./sqlalchemy/sql/schema.py", line 425, in _init
> self._autoload(metadata, autoload_with, include_columns)
>   File "./sqlalchemy/sql/schema.py", line 437, in _autoload
> self, include_columns, exclude_columns
>File "./sqlalchemy/engine/base.py", line 1198, in run_callable
> return callable_(self, *args, **kwargs)
>File "./sqlalchemy/engine/default.py", line 355, in reflecttable
> return insp.reflecttable(table, include_columns, exclude_columns)
>   File "./sqlalchemy/engine/reflection.py", line 463, in reflecttable
> for col_d in self.get_columns(table_name, schema,
> **table.dialect_kwargs):
> TypeError: get_columns() keywords must be strings
>
>
> with metadata.reflect(), OK.  Can you please make a very short and
> self-contained test case and post a bug report?  thanks.
>
>
>  --
> 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/E3MhX1m8QqQ/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/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.


Re: [sqlalchemy] problems with mysql reflect

2014-07-10 Thread Paul Molodowitch
Whoops! Just noticed this was the totally wrong traceback!

Here's the correct trace:

Traceback (most recent call last):
  File "", line 1, in 
  File "test.py", line 155, in 
metadata.reflect(db.engine, only=tables)
  File "./sqlalchemy/sql/schema.py", line 3277, in reflect
Table(name, self, **reflect_opts)
  File "./sqlalchemy/sql/schema.py", line 352, in __new__
table._init(name, metadata, *args, **kw)
  File "./sqlalchemy/sql/schema.py", line 425, in _init
self._autoload(metadata, autoload_with, include_columns)
  File "./sqlalchemy/sql/schema.py", line 437, in _autoload
self, include_columns, exclude_columns
  File "./sqlalchemy/engine/base.py", line 1198, in run_callable
return callable_(self, *args, **kwargs)
  File "./sqlalchemy/engine/default.py", line 355, in reflecttable
return insp.reflecttable(table, include_columns, exclude_columns)
  File "./sqlalchemy/engine/reflection.py", line 463, in reflecttable
for col_d in self.get_columns(table_name, schema,
**table.dialect_kwargs):
TypeError: get_columns() keywords must be strings
​

-- 
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] problems with mysql reflect

2014-07-09 Thread Paul Molodowitch
Sure - I think it's the same as the original poster's, but the traceback
I'm getting is:

>>> inspect(Project).relationships
Traceback (most recent call last):
  File "", line 1, in 
  File "./sqlalchemy/util/langhelpers.py", line 712, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
  File "./sqlalchemy/orm/mapper.py", line 2037, in relationships
return self._filter_properties(properties.RelationshipProperty)
  File "./sqlalchemy/orm/mapper.py", line 2054, in _filter_properties
configure_mappers()
  File "./sqlalchemy/orm/mapper.py", line 2560, in configure_mappers
mapper._post_configure_properties()
  File "./sqlalchemy/orm/mapper.py", line 1673, in
_post_configure_properties
prop.init()
  File "./sqlalchemy/orm/interfaces.py", line 143, in init
self.do_init()
  File "./sqlalchemy/orm/relationships.py", line 1510, in do_init
self._setup_join_conditions()
  File "./sqlalchemy/orm/relationships.py", line 1586, in
_setup_join_conditions
can_be_synced_fn=self._columns_are_mapped
  File "./sqlalchemy/orm/relationships.py", line 1849, in __init__
self._determine_joins()
  File "./sqlalchemy/orm/relationships.py", line 1915, in _determine_joins
consider_as_foreign_keys=consider_as_foreign_keys
  File "", line 2, in join_condition
  File "./sqlalchemy/sql/selectable.py", line 692, in _join_condition
b.foreign_keys,
AttributeError: 'tuple' object has no attribute 'foreign_keys'



On Wed, Jul 9, 2014 at 2:04 PM, Mike Bayer  wrote:

>
> On 7/9/14, 3:41 PM, Paul Molodowitch wrote:
>
> I just ran into the same problem, using python 2.6 + sqlalchemy 0.9.4 /
> 0.9.6 + MySQL.
>
>  The problem in my case IS definitely related to python 2.6 - basically,
> python 2.6 doesn't allow unicode keywords, while 2.7 does. Ie, if you do
> this:
>
>   def foo(**kwargs):
>   print kwargs
>  foo(**{u'thing':1})
>
>
>  ...it will work in 2.7, but give this error in 2.6:
>
>  TypeError: foo() keywords must be strings
>
>
>  For reference, these were the table.dialect_kwargs.keys() that were
> making trouble in 2.6:
>
>  [u'mysql_comment', u'mysql_engine', u'mysql_default charset']
>
>
>  Fine, except for the fact that they're unicode...
>
> OK but this is not a codepath within SQLAlchemy's MySQL reflection code.
> I'm PDBing right now into 0.9, using py2.6 + use_unicode=1; the reflected
> table options are sent directly into table.kwargs, not using the
> constructor or any **kw system.  the tests pass, and the keys are coming
> back as u''.
>
> if you can show me where table.kwargs gets used implicitly as a
> constructor arg i can fix that.
>
>  --
> 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/E3MhX1m8QqQ/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/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.


Re: [sqlalchemy] problems with mysql reflect

2014-07-09 Thread Paul Molodowitch
I just ran into the same problem, using python 2.6 + sqlalchemy 0.9.4 / 
0.9.6 + MySQL.

The problem in my case IS definitely related to python 2.6 - basically, 
python 2.6 doesn't allow unicode keywords, while 2.7 does. Ie, if you do 
this:

def foo(**kwargs):
print kwargs
foo(**{u'thing':1})


...it will work in 2.7, but give this error in 2.6:

TypeError: foo() keywords must be strings


For reference, these were the table.dialect_kwargs.keys() that were making 
trouble in 2.6:

[u'mysql_comment', u'mysql_engine', u'mysql_default charset']


Fine, except for the fact that they're unicode...

-- 
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] Automatically set cascade settings based on "ON DELETE" / "ON UPDATE" when reflecting?

2014-07-03 Thread Paul Molodowitch
I wasn't advocating making this connection "in general" (though I like the
autoconfigure option!), but only specifically for the case of reflection -
in this case, we know the DB supports it, and it would result in a better
python interface to the already existing tables.


On Thu, Jul 3, 2014 at 3:20 PM, Mike Bayer  wrote:

>
> On 7/3/14, 6:15 PM, Mike Bayer wrote:
> > On 7/3/14, 5:45 PM, Paul Molodowitch wrote:
> >> I noticed that sqlalchemy now properly sets the onpudate / ondelete
> >> properties of foreign keys when reflecting tables:
> >>
> >>
> https://bitbucket.org/zzzeek/sqlalchemy/issue/2183/support-on-delete-update-in-foreign-key
> >>
> >> However, it doesn't seem to set the cascade properties of
> >> relationships to reflect these properties. ie, if the Child table
> >> references the Parent table with a foreign key that has "ON DELETE
> >> CASCADE", and the reference column does not allow NULL, when you
> >> delete a parent table that has children, you will get an error,
> >> because sqlalchemy will try to set the child's ref to NULL.
> >>
> >> ideally we should add "delete" in the relationship's cascade
> >> properties (and probably delete-orphan as well), and then set
> >> passive_updates=True.
> >>
> >> Or am I missing something obvious  / doing something wrong / etc?
> > the configuration of a Column or ForeignKey has never been directly
> > linked to how relationship() gets configured.   passive_updates in
> > particular is a thorny one as not every database supports ON UPDATE
> > CASCADE, but for that matter not every database even supports ON DELETE
> > CASCADE.   There's also lots of variants to ON UPDATE and ON DELETE and
> > SQLAlchemy has no awareness of any of these directly.
> >
> > If we were to explore some automatic configuration of relationship based
> > on these attributes of ForeignKey, it would take place within the
> > automap extension: see
> > http://docs.sqlalchemy.org/en/rel_0_9/orm/extensions/automap.html.
> >
> > There are also recipes such that both relationship() and ForeignKey()
> > are generated at once, these are also good places for this kind of thing
> > to happen.  See
> >
> https://bitbucket.org/zzzeek/pycon2014_atmcraft/src/a6d96575bc497ce0c952bb81db9c05d054c98bb5/atmcraft/model/meta/orm.py?at=master
> > for an example of this, I still am thinking of a way recipes like this
> > could also be integrated into SQLAlchemy, possibly as an enhancement to
> > declarative.
>
> or a flag like "autoconfigure=True" on relationship().   this would also
> set up innerjoin=True for joined eager loading if the FK is not null.
> if the primaryjoin condition is too complex (has mulitple FKs),
> autoconfigure would raise an exception.
>
>
> --
> 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/WaVTCpBOVPk/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/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] Automatically set cascade settings based on "ON DELETE" / "ON UPDATE" when reflecting?

2014-07-03 Thread Paul Molodowitch
I noticed that sqlalchemy now properly sets the onpudate / ondelete 
properties of foreign keys when reflecting tables:

https://bitbucket.org/zzzeek/sqlalchemy/issue/2183/support-on-delete-update-in-foreign-key

However, it doesn't seem to set the cascade properties of relationships to 
reflect these properties. ie, if the Child table references the Parent 
table with a foreign key that has "ON DELETE CASCADE", and the reference 
column does not allow NULL, when you delete a parent table that has 
children, you will get an error, because sqlalchemy will try to set the 
child's ref to NULL.

ideally we should add "delete" in the relationship's cascade properties 
(and probably delete-orphan as well), and then set passive_updates=True.

Or am I missing something obvious  / doing something wrong / etc?

- Paul

-- 
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] Automatically set primary key to None when deleted?

2014-07-03 Thread Paul Molodowitch
>
> Particularly since sqlalchemy has already established that it's willing to
> expire dict members when they may not be valid anymore - ie, what it does
> to clear any "cached" values from a row proxy after the session is
> committed.
>
> well it doesn't expire the deleted object right now because it's been
> evicted from the Session by the time the commit goes to expire things.
> Changing that behavior now would definitely bite a lot of people who depend
> on how it is right now (other people who are also looking at their deleted
> objects against my recommendations... :) )
>

Makes sense - maybe it could be a configurable option? Dunno how many
people (besides me!) would be interested in such behavior, though... =P

> from sqlalchemy import inspect
>> def exists(session, obj):
>> state = inspect(obj)
>> return session.query(state.mapper).get(state.identity) is None
>>
>> print exists(sess, a1)
>>
>
>  Hmm... very interesting.  I'll have to read up what what exactly this is
> doing (ie, what is state.identity?)...
>
> it's documented here:
> http://docs.sqlalchemy.org/en/rel_0_9/orm/internals.html?highlight=instancestate#sqlalchemy.orm.state.InstanceState.identity
>
>
Thanks for the link!

 the unique constraints are a set though.   not necessarily deterministic
which one it would locate first.  I'd use more of some kind of declared
system on the class:

>
>  Not clear on why this matters - if we're iterating through all the
> constraints, and returning True if any of them is matched, what difference
> does it make which one is evaluated first?  Except potentially from a
> performance standpoint, I suppose...
>
> what if there are two constraints, and only one is satisfied for a given
> object's values (e.g. the constraint is now satisfied by some other row),
> the other one is not present.  Is the answer True or False?
>

In the scenario I was envisioning, True (ie, it exists).  Basically, "Would
it violate ANY unique constraints if I tried to insert it? Yes".

Of course, I see your point: that in some situations, this might not fit
conceptually with the answer to the question, "Does THIS object exist in
the database?"  But I guess that's likely your point... that there isn't
really a good "universal" way to answer that question.

-- 
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] Automatically set primary key to None when deleted?

2014-07-03 Thread Paul Molodowitch
On Wed, Jul 2, 2014 at 9:22 PM, Mike Bayer  wrote:

>
> On 7/2/14, 10:05 PM, Paul Molodowitch wrote:
>
>  Suppose I have a super simple table like this:
>
>   class Dinosaur(Base):
>  __tablename__ = 'dinosaurs'
>  id = Column(Integer, primary_key=True)
>  name = Column(String(255))
>
>
>  We assume that the id is set up in such a way that by default it always
> gets a unique value - ie, it uses autoincrement in MySQL, or a sequence in
> postgres, etc.
>
>  Now, suppose I get an instance of this class, and then delete it:
>
>   steggy = session.query(Dinosaur).filter_by(name='Steggy').one()
>  print steggy.id
>  session.delete(steggy)
>  session.commit()
>  print steggy.id
>
>
>  What I'd ideally like to see is that it first print the id of the row
> that it pulled from the database, and then print 'None':
>
>  30
> None
>
>
>  Is there any way that I can configure the id column / property so that
> it is automatically "cleared" on delete like this?
>
>
> the "steggy" object is a proxy for a database row.  when you delete that
> row, then commit the transaction, the object is detached from the session,
> and everything on it is expired.  there is no row.  check
> inspect(steggy).deleted, it will say True - that means in your system, the
> object is meaningless.  ideally no part of your program would be looking at
> that proxy any more, you should throw it away.  it means nothing.
>

That makes sense... but if if it really means nothing, and we shouldn't be
looking at it, then why keep it's attributes around at all?  Particularly
since sqlalchemy has already established that it's willing to expire dict
members when they may not be valid anymore - ie, what it does to clear any
"cached" values from a row proxy after the session is committed.

Of course, you could make the case that other pieces of the program may
want to inspect the data that was on there, after the fact... maybe you're
going to print out something that says, "RIP Steggy", or something - but in
that case, the one field that really DOESN'T make any sense in this case
(and it seems like it would be a common pattern!) is the one that exists
solely as a means to look it up in the database, it's auto-incremented id
column.  Which is what prompted this question...


If not, as a consolation prize, I'd also be interested in the easiest way
> to query if a given instance exists in the database - ie, I could do
> something like:
>
>
>  session.exists(steggy)
>
>
>  OR
>
>  steggy.exists()
>
>
>
> from sqlalchemy import inspect
> def exists(session, obj):
> state = inspect(obj)
> return session.query(state.mapper).get(state.identity) is None
>
> print exists(sess, a1)
>

Hmm... very interesting.  I'll have to read up what what exactly this is
doing (ie, what is state.identity?)... It's possibly that
inspect(steggy).deleted may just give me what I need though. Thanks for
both those tips! (In case you couldn't tell, I'm still new to / exploring
sqlalchemy...)


> ...which, in this case, would simply run a query to see if any dinosaurs
> exist with the name "Steggy".
>
> that's totally different.  That's a WHERE criterion on the "name" field,
> which is not the primary key.  that's something specific to your class
> there.
>

True.  There's really no way for a generic "exists" function to know what
conditions you want to query a generic class on to determine "existence."
 Which is why I was suggesting the uniqueness constraint...

 Needing to set up some extra parameters to make this possible - such as
adding a unique constraint on the name column -

> OK, so you want a function that a. receives an object b. looks for UNIQUE
> constraints on it c. queries by those unique constraints (I guess you want
> the first one present?  not clear.  a table can have a lot of unique
> constraints on it) that would be:
>

Sort of - the thinking here was that you could just ask, "If I tried to
insert this object into the table, would it violate any uniqueness
constraints?", and get back a boolean result... and you could use that as a
reasonable heuristic for determining existence, in a fairly generic way.


> from sqlalchemy import inspect, UniqueConstraint
> def exists(session, obj):
> state = inspect(obj)
> table = state.mapper.local_table
> for const in table.constraints:
> if isinstance(const, UniqueConstraint):
>crit = and_(*[col == getattr(obj, col.key) for col in const])
>return session.query(state.mapper).filter(crit).count() > 0
> else:
> 

[sqlalchemy] Automatically set primary key to None when deleted?

2014-07-02 Thread Paul Molodowitch
Suppose I have a super simple table like this:

class Dinosaur(Base):
__tablename__ = 'dinosaurs'
id = Column(Integer, primary_key=True)
name = Column(String(255))


We assume that the id is set up in such a way that by default it always 
gets a unique value - ie, it uses autoincrement in MySQL, or a sequence in 
postgres, etc.

Now, suppose I get an instance of this class, and then delete it:

steggy = session.query(Dinosaur).filter_by(name='Steggy').one()
print steggy.id
session.delete(steggy)
session.commit()
print steggy.id


What I'd ideally like to see is that it first print the id of the row that 
it pulled from the database, and then print 'None':

30
None


Is there any way that I can configure the id column / property so that it 
is automatically "cleared" on delete like this?


If not, as a consolation prize, I'd also be interested in the easiest way 
to query if a given instance exists in the database - ie, I could do 
something like:

session.exists(steggy)


OR

steggy.exists()


...which, in this case, would simply run a query to see if any dinosaurs 
exist with the name "Steggy".  Needing to set up some extra parameters to 
make this possible - such as adding a unique constraint on the name column 
- would be potentially possible.  And yes, I know I can always fall back on 
just manually constructing a query against the name field myself...

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