Re: [sqlalchemy] trouble with a self-referential query and remote side population

2018-01-05 Thread Jonathan Vanasco


On Thursday, January 4, 2018 at 10:58:49 AM UTC-5, Mike Bayer wrote:
>
> that and, when you use contains_eager you need to tell it what entity 
> it's looking for when it considers columns as part of a relationship: 
>
> .options(sqlalchemy.orm.contains_eager('foo_alt', alias=Foo_2))\ 
>

As always, THANK YOU SO MUCH, MIKE. That alias kwarg was the missing bit. 
 The `foreign` was left over from the original query and wasn't removed by 
accident (the original doesn't fkey on a primary for the join). 
 

-- 
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] trouble with a self-referential query and remote side population

2018-01-04 Thread Mike Bayer
On Wed, Jan 3, 2018 at 7:48 PM, Mike Bayer  wrote:
> didn't look close yet but you wouldn't want to have foreign() on a
> column that is a primary key column.   should be on the opposite side
> of whatever refers to a primary key.

that and, when you use contains_eager you need to tell it what entity
it's looking for when it considers columns as part of a relationship:

qedge_case = s.query(Foo)\
.join(Foo_2,
  Foo.id_foo_alt == Foo_2.id
  )\
.filter(Foo_2.name.op('IS NOT')(None),
)\
.options(sqlalchemy.orm.contains_eager('foo_alt', alias=Foo_2))\
.order_by(Foo.id.asc())





>
> On Wed, Jan 3, 2018 at 6:28 PM, Jonathan Vanasco  
> wrote:
>> i've got a handful of bad data from some edge cases and have been having
>> trouble querying the data with sqlalchemy.  i attached a SSCCE below.
>>
>> my cleanup script imports the model, extends `Main_Foo` with a new
>> relationship, and creates 2 aliases.
>>
>> this selects the right rows (2 and 4) but the relationship is populated with
>> the "local side" data, not the  "remote side" data
>>
>> i'm sure I'm missing something obvious.
>>
>>
>>
>> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - -
>> # Standard imports
>>
>>
>> import sqlalchemy
>> import sqlalchemy.orm
>>
>>
>> from sqlalchemy.ext.declarative import declarative_base
>> from sqlalchemy import Integer, Column, Unicode
>>
>>
>> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - -
>> # You probably don't need to overwrite this
>> Base = declarative_base()
>>
>>
>> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - -
>> # Define some models that inherit from Base
>>
>>
>> class Main_Foo(Base):
>> __tablename__ = 'main_foo'
>> id = Column(Integer, primary_key=True)
>> id_foo_alt = Column(Integer)
>> name = Column(Unicode)
>>
>>
>>
>> # need to define these separately as they're in a new script that overwrites
>> the model
>> Main_Foo.foo_alt = sqlalchemy.orm.relationship(
>> "Main_Foo",
>> primaryjoin="Main_Foo.id_foo_alt==remote(foreign(Main_Foo.id))",
>> uselist=False,
>> )
>> Foo = sqlalchemy.orm.aliased(Main_Foo, name='foo')
>> Foo_2 = sqlalchemy.orm.aliased(Main_Foo, name='foo2')
>>
>>
>> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - -
>> # set the engine
>>
>>
>> engine = sqlalchemy.create_engine('sqlite:///:memory:', echo=True)
>> Base.metadata.create_all(engine)
>>
>>
>> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
>> - -
>> # do a simple query to trigger the mapper error
>>
>>
>> sessionFactory = sqlalchemy.orm.sessionmaker(bind=engine)
>> s = sessionFactory()
>>
>>
>> rows = ((1, None, 'a (ab)'),
>> (2, 1, 'b (ab)'),
>> (3, None, 'c (cd)'),
>> (4, 3, 'd (cd)'),
>> (5, None, 'e'),
>> (6, 'x', 'f'),
>> (7, 'x', 'g'),
>> )
>> for row in rows:
>> f = Main_Foo()
>> f.id = row[0]
>> f.id_foo_alt = row[1]
>> f.name = row[2]
>> s.add(f)
>> s.flush()
>> s.commit()
>>
>>
>> qedge_case = s.query(Foo)\
>> .join(Foo_2,
>>   Foo.id_foo_alt == Foo_2.id
>>   )\
>> .filter(Foo_2.name.op('IS NOT')(None),
>> )\
>> .options(sqlalchemy.orm.contains_eager('foo_alt'))\
>> .order_by(Foo.id.asc())
>>
>>
>> for f in qedge_case.all():
>> print "---"
>> print f.id
>> print " %s %s" % (f.id, f.name)
>> print " > >"
>> print " %s %s" % (f.foo_alt.id, f.foo_alt.name)
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>
>> --
>> 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.

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

Re: [sqlalchemy] trouble with a self-referential query and remote side population

2018-01-03 Thread Mike Bayer
didn't look close yet but you wouldn't want to have foreign() on a
column that is a primary key column.   should be on the opposite side
of whatever refers to a primary key.

On Wed, Jan 3, 2018 at 6:28 PM, Jonathan Vanasco  wrote:
> i've got a handful of bad data from some edge cases and have been having
> trouble querying the data with sqlalchemy.  i attached a SSCCE below.
>
> my cleanup script imports the model, extends `Main_Foo` with a new
> relationship, and creates 2 aliases.
>
> this selects the right rows (2 and 4) but the relationship is populated with
> the "local side" data, not the  "remote side" data
>
> i'm sure I'm missing something obvious.
>
>
>
> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - -
> # Standard imports
>
>
> import sqlalchemy
> import sqlalchemy.orm
>
>
> from sqlalchemy.ext.declarative import declarative_base
> from sqlalchemy import Integer, Column, Unicode
>
>
> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - -
> # You probably don't need to overwrite this
> Base = declarative_base()
>
>
> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - -
> # Define some models that inherit from Base
>
>
> class Main_Foo(Base):
> __tablename__ = 'main_foo'
> id = Column(Integer, primary_key=True)
> id_foo_alt = Column(Integer)
> name = Column(Unicode)
>
>
>
> # need to define these separately as they're in a new script that overwrites
> the model
> Main_Foo.foo_alt = sqlalchemy.orm.relationship(
> "Main_Foo",
> primaryjoin="Main_Foo.id_foo_alt==remote(foreign(Main_Foo.id))",
> uselist=False,
> )
> Foo = sqlalchemy.orm.aliased(Main_Foo, name='foo')
> Foo_2 = sqlalchemy.orm.aliased(Main_Foo, name='foo2')
>
>
> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - -
> # set the engine
>
>
> engine = sqlalchemy.create_engine('sqlite:///:memory:', echo=True)
> Base.metadata.create_all(engine)
>
>
> # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
> - -
> # do a simple query to trigger the mapper error
>
>
> sessionFactory = sqlalchemy.orm.sessionmaker(bind=engine)
> s = sessionFactory()
>
>
> rows = ((1, None, 'a (ab)'),
> (2, 1, 'b (ab)'),
> (3, None, 'c (cd)'),
> (4, 3, 'd (cd)'),
> (5, None, 'e'),
> (6, 'x', 'f'),
> (7, 'x', 'g'),
> )
> for row in rows:
> f = Main_Foo()
> f.id = row[0]
> f.id_foo_alt = row[1]
> f.name = row[2]
> s.add(f)
> s.flush()
> s.commit()
>
>
> qedge_case = s.query(Foo)\
> .join(Foo_2,
>   Foo.id_foo_alt == Foo_2.id
>   )\
> .filter(Foo_2.name.op('IS NOT')(None),
> )\
> .options(sqlalchemy.orm.contains_eager('foo_alt'))\
> .order_by(Foo.id.asc())
>
>
> for f in qedge_case.all():
> print "---"
> print f.id
> print " %s %s" % (f.id, f.name)
> print " > >"
> print " %s %s" % (f.foo_alt.id, f.foo_alt.name)
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
> --
> 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.

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