[sqlalchemy] Re: Polymorphic self referential foreign key in sqlalchemy

2015-07-23 Thread Douglas Russell
Perfect, thanks!

On Monday, 20 July 2015 10:49:26 UTC-4, Douglas Russell wrote:

 Apologies for cross-posting this, but I realised that this might be a 
 better place to get an answer than this Stackoverflow question 
 http://stackoverflow.com/questions/31393824/polymorphic-self-referential-foreign-key-in-sqlalchemy
  
 that I asked a week ago.

 I am trying to resolve a problem with a self-referential table with Joined 
 Table Inheritance where there is a foreign key linking the inheritance 
 relationships, but then also a case where a class has an additional 
 reference to an instance of its parent. Best to go with a simplified 
 example:

 Class B inherits from Class A. Class B is linked to Class A by the id 
 column through the Foreign Key in Class B. Class B also has a column (a_id) 
 which references Class A which has nothing to do with the inheritance.

 from sqlalchemy import Column, Integer,ForeignKey, create_enginefrom 
 sqlalchemy.ext.declarative import declarative_basefrom sqlalchemy.orm import 
 sessionmaker, relationship, backref
 Base = declarative_base()

 class A(Base):
 __tablename__ = 'a'
 satype = Column(String(50))
 __mapper_args__ = {
 'polymorphic_identity': 'a',
 'polymorphic_on': satype
 }

 id = Column(Integer, primary_key=True)

 class B(A):
 __tablename__ = 'b'

 id = Column(Integer, ForeignKey('a.id'), primary_key=True)

 __mapper_args__ = {
 'polymorphic_identity': 'b'
 }

 a_id = Column(Integer, ForeignKey('a.id'))
 a = relationship('A', backref='b')

 engine = create_engine('sqlite:///:memory:', 
 echo=True)Base.metadata.create_all(engine)Session = sessionmaker(bind=engine)
 session = Session()

 As per the documentation 
 http://docs.sqlalchemy.org/en/latest/orm/relationship_persistence.html#rows-that-point-to-themselves-mutually-dependent-rows,
  
 I would resolve the case where there are multiple ForeignKeys between 
 tables by explicitly specifying in the relationship which was to be used.

 class B(A):
 __tablename__ = 'b'

 id = Column(Integer, ForeignKey('a.id'), primary_key=True)

 __mapper_args__ = {
 'polymorphic_identity': 'b'
 }

 a_id = Column(Integer, ForeignKey('a.id'))
 # I know the primaryjoin is no longer needed in SA = 0.8
 a = relationship('A', backref='b', foreign_keys=[a_id], 
 primaryjoin=a_id==A.id)

 I think the problem is that I don't seem to be able to figure out how to 
 do the same for the polymorphic column id as I am not explicitly defining 
 that relationship.

 Cheers,

 Douglas



-- 
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] marking an object read-only / recursive expunge?

2015-07-23 Thread Jonathan Vanasco
So my code above is just completely wrong.  

This code actually does what one expects:

def recursive_expunge(obj, dbSession):
def _recursive_expunge(_obj):
_instance_state = sqlalchemy.inspection.inspect(_obj)
_mapper = _instance_state.mapper
try:
dbSession.expunge(_obj)
# print expunge | %s % _obj
except sqlalchemy.orm.exc.UnmappedInstanceError:
# print sqlalchemy.orm.exc.UnmappedInstanceError | %s % 
_obj
pass
except sqlalchemy.exc.InvalidRequestError:
# print sqlalchemy.exc.UnmappedInstanceError | %s % _obj
pass
if _mapper:
# _unloaded = [(_name, _rel) for (_name, _rel) in 
_mapper.relationships.items() if _name in _instance_state.unloaded]
_loaded_rels = [i for i in _mapper.relationships.items() if 
i[0] not in _instance_state.unloaded]
for (_name, _rel) in _loaded_rels:
_loaded_rel_data = getattr(_obj, _name)
if _loaded_rel_data:
if not _rel.uselist:
_recursive_expunge(_loaded_rel_data)
else:
for _i in _loaded_rel_data:
_recursive_expunge(_i)
_recursive_expunge(obj)

-- 
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] question about `sqlalchemy.orm.mapper.Mapper` and objects

2015-07-23 Thread Jonathan Vanasco
Yeah, no error.

I'll guess that:

* My code isn't doing what I intended
* but
*SqlAlchemy isn't raising an error

So I can work with that. 

-- 
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] Disabling implicit lazy loading

2015-07-23 Thread Mike Bayer



On 7/23/15 10:09 AM, Mike Bayer wrote:



On 7/23/15 1:24 AM, Yegor Roganov wrote:

Hi all!
Is there a way to disable implicit loading of relationships?
For example, I want an exception to be thrown if I try to access 
'address.user' unless user was explicitly loaded via options


address =
query(Address).options(joinedload(Address.user)).filter_by(id=id).first();
address.user   # OK
address = query(Address).get(id); address.user # should throw


At first I thought that `noload` option is what I need, but it seems 
it disables event explicit loading.
noload is how you'd disable implicit loading.   As far as throwing on 
a lazyload, the easiest way is just to detach the objects from their 
parent Session so they no longer have any connectivity using 
session.expunge(object), but then you're no longer in the session.


Otherwise, it seems the problem you are actually trying to solve is 
raising on unexpected SQL.   lazy loading of relationships is not the 
only thing that goes on, there are loads of unloaded columns, columns 
that had server defaults emitted on the last flush, loads of 
joined-inheritance rows, all kinds. this is why the best approach 
is to just do real profiling of your applications using SQL logging, 
or perhaps using SQL events like before_execute()  / 
before_cursor_execute() so that you can build yourself a with 
assert_no_sql(session): -style context manager for critical blocks 
that should have no SQL emitted.



Guessing that's not what you want. Feel free to write your own 
NoLoader that just raises, example:


whoops.  Let's try that again, this one actually works:

from sqlalchemy.orm import properties
from sqlalchemy.orm import strategies
from sqlalchemy.orm import state


@properties.RelationshipProperty.strategy_for(lazy=raise)
class RaiseLoader(strategies.NoLoader):
note: this is *very SQLAlchemy 1.0 specific*!!
it will need to be reviewed for 1.1

def create_row_processor(
self, context, path, loadopt, mapper,
result, adapter, populators):

def invoke_no_load(state, passive):
raise Exception(boom)
set_lazy_callable = state.InstanceState.\
_instance_level_callable_processor(
mapper.class_manager,
invoke_no_load,
self.key
)
populators[new].append((self.key, set_lazy_callable))



--
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] Disabling implicit lazy loading

2015-07-23 Thread Mike Bayer



On 7/23/15 1:24 AM, Yegor Roganov wrote:

Hi all!
Is there a way to disable implicit loading of relationships?
For example, I want an exception to be thrown if I try to access 
'address.user' unless user was explicitly loaded via options


address =
query(Address).options(joinedload(Address.user)).filter_by(id=id).first();
address.user   # OK
address = query(Address).get(id); address.user # should throw


At first I thought that `noload` option is what I need, but it seems 
it disables event explicit loading.
noload is how you'd disable implicit loading.   As far as throwing on a 
lazyload, the easiest way is just to detach the objects from their 
parent Session so they no longer have any connectivity using 
session.expunge(object), but then you're no longer in the session.


Otherwise, it seems the problem you are actually trying to solve is 
raising on unexpected SQL.   lazy loading of relationships is not the 
only thing that goes on, there are loads of unloaded columns, columns 
that had server defaults emitted on the last flush, loads of 
joined-inheritance rows, all kinds. this is why the best approach is 
to just do real profiling of your applications using SQL logging, or 
perhaps using SQL events like before_execute()  / 
before_cursor_execute() so that you can build yourself a with 
assert_no_sql(session): -style context manager for critical blocks that 
should have no SQL emitted.



Guessing that's not what you want. Feel free to write your own 
NoLoader that just raises, example:


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


@properties.RelationshipProperty.strategy_for(lazy=raise)
class RaiseLoader(strategies.NoLoader):
note: this is *very SQLAlchemy 1.0 specific*!!   it will need to 
be reviewed for 1.1


def create_row_processor(
self, context, path, loadopt, mapper,
result, adapter, populators):
def invoke_no_load(state, dict_, row):
raise Exception(boom)
populators[new].append((self.key, invoke_no_load))

Base = declarative_base()


class A(Base):
__tablename__ = 'a'
id = Column(Integer, primary_key=True)
bs = relationship(B, lazy=raise)


class B(Base):
__tablename__ = 'b'
id = Column(Integer, primary_key=True)
a_id = Column(ForeignKey('a.id'))

e = create_engine(sqlite://, echo=True)
Base.metadata.create_all(e)

s = Session(e)
s.add(A(bs=[B(), B()]))
s.commit()

a1 = s.query(A).first()
a1.bs   # boom


send me a PR that includes tests and I can consider this for 1.1.








If you are intrested why I need this kind of functionality, that's 
because I found it hard to manage which relationships were loaded and 
which not, and it may result in dozens of unwanted DB queries.

--
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 
mailto:sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com 
mailto: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] natural vs surrogate keys for user groups?

2015-07-23 Thread Iain Duncan
Hi folks, I'm starting a green field project and one component is a stand
alone auth micro service. It will have one job only, log people in and set
their group list. After that, the group list and user id will be going in
jwt tokens and will be used in subsequent apps as fields for the remote
user in the wsgi env.

This has me wondering whether I should be using natural primary keys for
the group id to further simplify things, it seems like it would make life
easier but as I have only, to this day, used surrogate integer keys, I
don't really know the downsides of them. Would love to hear feedback from
anyone on this or similar issues.

thanks!
(And it's nice to be getting back to SQAlchemy from Angular land, woot!)

Iain

-- 
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] best books on DB design for sqlalchemy users?

2015-07-23 Thread Iain Duncan
I feel like I should really take up my db game for an upcoming set of
projects, and am wondering if there are any real standout books on db
design that fit well with the design philosophy of SQLA. Recos much
appreciated!

thanks
Iain

-- 
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] Many-to-Many Table

2015-07-23 Thread Mike Bayer



On 7/23/15 2:18 PM, Rich Shepard wrote:
  Originally posted here on June 4th, but no one responded. I'm now 
back on
this project and this should be the last table I need to add to the 
schema.
I would appreciate your review of the below class and whether it is 
good to

go or needs your modifications.

  Section 2.1.15 in the 1.0.8 manual describes building an association 
table
for many-to-many relationships. My application has a table that 
associates

multiple locations with multiple types of data collected. That is, each
location can have multiple types of data collected, and each data type 
can

be collected at multiple locations. There are other attributes associated
with each row. Will the following table declaration work? Or, do I 
separate

site and param into a separate table from the other columns?



conceptually not a big deal but API-wise has many mistakes. Sequences 
don't work with unicode, there is no value parameter, the table has no 
primary key.


--
class Monitoring(Base):
__table_name__ = 'monitoring'
permit_nbr = Column(Unicode(24), ForeignKey('permits.nbr'))
permit = relationship(Permits, back_populates = 'locations')
data_type = Column(Unicode(16), CheckConstraint(data_type IN 
('surface \

water', 'ground water', 'air', 'benthos', 'fish', 'microbes', \
'physical','weather')))
site = Column(Unicode(12), Sequence('location_seq'), nullable = 
False, \

unique = True, ForeignKen('locations.site_id'))
param = Column(Unicode(24), nullable = False, unique = True, 
ForeignKey(\

'conditions.param_name'))
mcl = Column(Float)
monit_freq = Column(Unicode(12), value = 'Month', nullable = False, \
CheckConstraint(monitor_freq IN ('Hour','Shift','Day','Week','2x 
month',\

'Month','Quarter','Semi-Annual','Annual')))
rpt_freq = Column(Unicode(12), value = 'Month', nullable = False, \
CheckConstraint(rpt_freq IN ('Hour','Shift','Day','Week','2x 
month',\

'Month','Quarter','Semi-Annual','Annual')))
start_date = Column(Date, value = today, nullable = False)
end_date = Column(Date)
site = relationship(Locations, back_populates = 'monitoring')
param = relationship(Conditions, back_populates = 'monitoring')
-

Rich


--
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] Many-to-Many Table

2015-07-23 Thread Rich Shepard

On Thu, 23 Jul 2015, Mike Bayer wrote:


conceptually not a big deal but API-wise has many mistakes. Sequences
don't work with unicode, there is no value parameter, the table has no
primary key.


Mike,

  True, I don't want a sequence but the location ID, there needs to be a
value column, and others should be moved into the parameter table.

  I thought a many-to-many table did not need a primary key because it would
be accessed by (in this case) location or paramter.

Thanks,

Rich


Re: [sqlalchemy] question about `sqlalchemy.orm.mapper.Mapper` and objects

2015-07-23 Thread Mike Bayer


On 7/23/15 3:04 PM, Jonathan Vanasco wrote:

so does

dbSession.expunge(relationship)

when `relationship` is an item 
from `sqlalchemy.inspection.inspect(obj).mapper.relationships.values()` somehow 
expunge the object-specific relationship, or all relationships ?


that should raise an error, though I wouldn't be surprised if that ends 
up in an unchecked AttributeError right now.   expunge is for instances, 
not mappings.






--
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 
mailto:sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com 
mailto: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] question about `sqlalchemy.orm.mapper.Mapper` and objects

2015-07-23 Thread Jonathan Vanasco
This is an extension of my question about recursive object expunging 
(https://groups.google.com/forum/#!topic/sqlalchemy/lUhCDfkPc9k)

Is the mapper that is accessed via 
`sqlalchemy.inspection.inspect(obj).mapper` and stored in 
`object.__mapper__` specific to the instance?

I thought it was the global mapper, but looking at how it behaves as I use 
it... it seems local to the 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/d/optout.


Re: [sqlalchemy] question about `sqlalchemy.orm.mapper.Mapper` and objects

2015-07-23 Thread Mike Bayer



On 7/23/15 2:28 PM, Jonathan Vanasco wrote:
This is an extension of my question about recursive object expunging 
(https://groups.google.com/forum/#!topic/sqlalchemy/lUhCDfkPc9k)


Is the mapper that is accessed via 
`sqlalchemy.inspection.inspect(obj).mapper` and stored in 
`object.__mapper__` specific to the instance?


I thought it was the global mapper, but looking at how it behaves as I 
use it... it seems local to the object.

there's no object-local mappers.





--
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 
mailto:sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com 
mailto: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] Many-to-Many Table

2015-07-23 Thread Rich Shepard

  Originally posted here on June 4th, but no one responded. I'm now back on
this project and this should be the last table I need to add to the schema.
I would appreciate your review of the below class and whether it is good to
go or needs your modifications.

  Section 2.1.15 in the 1.0.8 manual describes building an association table
for many-to-many relationships. My application has a table that associates
multiple locations with multiple types of data collected. That is, each
location can have multiple types of data collected, and each data type can
be collected at multiple locations. There are other attributes associated
with each row. Will the following table declaration work? Or, do I separate
site and param into a separate table from the other columns?

--
class Monitoring(Base):
__table_name__ = 'monitoring'
permit_nbr = Column(Unicode(24), ForeignKey('permits.nbr'))
permit = relationship(Permits, back_populates = 'locations')
data_type = Column(Unicode(16), CheckConstraint(data_type IN ('surface \
water', 'ground water', 'air', 'benthos', 'fish', 'microbes', \
'physical','weather')))
site = Column(Unicode(12), Sequence('location_seq'), nullable = False, \
unique = True, ForeignKen('locations.site_id'))
param = Column(Unicode(24), nullable = False, unique = True, ForeignKey(\
'conditions.param_name'))
mcl = Column(Float)
monit_freq = Column(Unicode(12), value = 'Month', nullable = False, \
CheckConstraint(monitor_freq IN ('Hour','Shift','Day','Week','2x month',\
'Month','Quarter','Semi-Annual','Annual')))
rpt_freq = Column(Unicode(12), value = 'Month', nullable = False, \
CheckConstraint(rpt_freq IN ('Hour','Shift','Day','Week','2x month',\
'Month','Quarter','Semi-Annual','Annual')))
start_date = Column(Date, value = today, nullable = False)
end_date = Column(Date)
site = relationship(Locations, back_populates = 'monitoring')
param = relationship(Conditions, back_populates = 'monitoring')
-

Rich


Re: [sqlalchemy] best books on DB design for sqlalchemy users?

2015-07-23 Thread Rich Shepard

On Thu, 23 Jul 2015, Iain Duncan wrote:


I feel like I should really take up my db game for an upcoming set of
projects, and am wondering if there are any real standout books on db
design that fit well with the design philosophy of SQLA. Recos much
appreciated!


Iain,

  Read Joe Celko's books, starting with the latest edition of SQL for
Smarties. I read his columns in Database Advisor and other magazines in the
1980s and have read and used almost all his books. You can't go wrong taking
the time to do it correctly from the gitgo.

Rich


Re: [sqlalchemy] best books on DB design for sqlalchemy users?

2015-07-23 Thread Richard Gerd Kuesters
not quite sqlalchemy related, but one of the best readings i've had 
about sql was SQL Anti-Patterns: 
https://pragprog.com/book/bksqla/sql-antipatterns


it is not about how to do sql right, it's about not to do certain types 
of sql, lol.




On 07/23/2015 01:35 PM, Rich Shepard wrote:

On Thu, 23 Jul 2015, Iain Duncan wrote:


I feel like I should really take up my db game for an upcoming set of
projects, and am wondering if there are any real standout books on db
design that fit well with the design philosophy of SQLA. Recos much
appreciated!


Iain,

  Read Joe Celko's books, starting with the latest edition of SQL for
Smarties. I read his columns in Database Advisor and other magazines 
in the
1980s and have read and used almost all his books. You can't go wrong 
taking

the time to do it correctly from the gitgo.

Rich


--
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.
attachment: richard.vcf