Hi,

Progress! But still not working 100%. I have three assert statements: one that 
tests a "to one" relationship across schemas, one that test a "to one" 
relationship within the same scheme, and two that test a "many to many" 
relationship across schemas (one assert for each direction).

When I set the search_path to what I'd like it to be (e.g. "things, people") 
and use the "connect" event listener as detailed earlier in this thread, the 
first two asserts (which broke before) now work. The first of the "many to 
many" asserts works, but the reverse does not. However, the relationship 
statements (in either direction) *do* seem to work. I can't explain that.

Going for it, I put the event listener into my large project and crossed my 
fingers, but it doesn't work. I'm still running into these errors across 
schemas:

ArgumentError: Could not determine join condition between parent/child tables 
on relationship VisitSpectrum.observation.  Specify a 'primaryjoin' expression. 
 If 'secondary' is present, 'secondaryjoin' is needed as well.

It works when I set the search path to "$user", i.e. no existing table, and 
different things break depending on the order search path. As far as I can tell 
the listener is setting the search path properly, but I have no idea how 
persistent it is or if another connection is being made somehow where it's not. 
So I'm getting frustrated.

Attached is my toy model where the relationship assertion breaks.

Demitri


-- 
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/sqlalchemy?hl=en.

#!/usr/bin/python

#from sqlalchemy import *
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.event import listen
from sqlalchemy.pool import Pool
from sqlalchemy.orm import relationship

"""
CREATE TABLE people.band ( id integer primary key, name text, venue_id integer );
CREATE TABLE things.venue ( id integer primary key, name text );
CREATE TABLE things.instrument ( id serial NOT NULL, label text, CONSTRAINT instrument_pk PRIMARY KEY (id))
CREATE TABLE people.musician
(
  id serial NOT NULL,
  age integer,
  band_id integer,
  CONSTRAINT musician_pk PRIMARY KEY (id ),
  CONSTRAINT band_fk FOREIGN KEY (band_id)
      REFERENCES people.band (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE RESTRICT
);
CREATE TABLE people.musician_to_instrument
(
  musician_id integer NOT NULL,
  instrument_id integer NOT NULL,
  CONSTRAINT musician_to_instrument_pk PRIMARY KEY (musician_id , instrument_id ),
  CONSTRAINT instrument_fk FOREIGN KEY (instrument_id)
      REFERENCES things.instrument (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION,
  CONSTRAINT musician_fk FOREIGN KEY (musician_id)
      REFERENCES people.musician (id) MATCH SIMPLE
      ON UPDATE CASCADE ON DELETE NO ACTION
)
ALTER TABLE ONLY people.band
    ADD CONSTRAINT venue_fk FOREIGN KEY (venue_id) REFERENCES things.venue(id) ON UPDATE CASCADE ON DELETE SET NULL;

"""

def my_on_connect(dbapi_con, connection_record):
    '''
    dbapi_con - type: psycopg2._psycopg.connection
    connection_record - type: sqlalchemy.pool._ConnectionRecord
    '''
    print "New DBAPI connection:"#, dbapi_con
    cursor = dbapi_con.cursor()

    cursor.execute("SHOW search_path");
    print "old: ",cursor.fetchone()[0];

    cursor.execute('SET search_path TO "$user"') # 

    cursor.execute("SHOW search_path");
    print "new: ",cursor.fetchone()[0];

listen(Pool, 'connect', my_on_connect)

#e = create_engine("postgresql://scott:tiger@localhost/test", echo=True)
e = create_engine("postgresql://schema_test:schema_test@localhost:9000/schema_test_db", echo=False)

Base = declarative_base(bind=e)

class Band(Base):
	__tablename__ = 'band'
	__table_args__ = {'autoload' : True, 'schema' : 'people'}

class Venue(Base):
	__tablename__ = 'venue'
	__table_args__ = {'autoload' : True, 'schema' : 'things'}

class Musician(Base):
	__tablename__ = 'musician'
	__table_args__ = {'autoload' : True, 'schema' : 'people'}

class Instrument(Base):
	__tablename__ = 'instrument'
	__table_args__ = {'autoload' : True, 'schema' : 'things'}

class MusicianToInstrument(Base):
	__tablename__ = 'musician_to_instrument'
	__table_args__ = {'autoload' : True, 'schema' : 'people'}


# Strangely, both of the two statements below work.

#Musician.instruments = relationship(Instrument,
#								 secondary=MusicianToInstrument.__table__,
#								 backref="musicians")
#Instrument.musicians = relationship(Musician,
#								secondary=MusicianToInstrument.__table__,
#								backref="instruments")

assert Band.__table__.c.venue_id.references(Venue.__table__.c.id)
assert Musician.__table__.c.band_id.references(Band.__table__.c.id)
assert MusicianToInstrument.__table__.c.musician_id.references(Musician.__table__.c.id)

# fails
assert MusicianToInstrument.__table__.c.instrument_id.references(Instrument.__table__.c.id)

Reply via email to