[sqlalchemy] Re: ORM Many to Many Across Two Databases

2009-10-15 Thread Luke Arno
My apologies. I must have misunderstanding the behavior of
the schema option and thus its intent. How do I configure a
relation across two logical databases using schema?

I have tried the following:

engine = create_engine(DATABASEURI, echo=True)
meta = MetaData()
meta.bind = engine

left_schema = LeftDatabaseName
right_schema = RightDatabaseName

left_table = Table('LeftTable', meta,
Column('id', Integer, primary_key=True),
Column('description', String(128)),
schema=left_schema)

right_table = Table('RightTable', meta,
Column('id', Integer, primary_key=True),
Column('description', String(128)),
schema=right_schema)

assoc_table = Table('LeftAssoc', meta,
Column('left_id', Integer),
Column('right_id', Integer),
#quote_schema=False,
schema=left_schema)

MySession = sessionmaker(bind=engine)

class MyBase(object):
def __init__(self, description):
self.description = description
def __str__(self):
return str(self.description)

class Left(MyBase): pass

class Right(MyBase): pass

mapper(Left, left_table)
mapper(Right, right_table, properties={
'lefts': relation(Left, secondary=assoc_table,
primaryjoin=(right_table.c.id==assoc_table.c.right_id),
secondaryjoin=(assoc_table.c.left_id==left_table.c.id),
foreign_keys=[assoc_table.c.left_id, assoc_table.c.right_id],
backref=rights),
})

if __name__ == '__main__':
meta.drop_all()
meta.create_all()
session = MySession()
left1 = Left('Left 1')
left2 = Left('Left 2')
right1 = Right('Right 1')
right2 = Right('Right 2')
left1.rights.extend([right1, right2])
right1.lefts.extend([left1, left2])
session.add_all([left1, left2, right1, right2])
session.commit()

left1 = session.query(Left).filter_by(description=Left 1).one()
print left1
for right in left1.rights:
print  *4, right
for left in right.lefts:
print  *8, left

The table name in the generated SQL is DBNAME.TABLENAME,
which doesn't work. It needs to be

DBNAME.SCHEMANAME.TABLENAME
or
DBNAME..TABLENAME (uses default schema)

I tried using quote_schema=False and adding a . to the end
of the schema value (schema=DBNAME.) but this results in
the broken SQL mentioned earlier:

SELECT [LeftTable_1].description AS [DBNAME._LeftTab_1]

Using schema=DBNAME.SCHEMANAME didn't work either.

Please let me know how to do this correctly.

I am using:

SQL Server 8.0
Hardy Heron
Python 2.5
SQLAlchemy 0.5.6
pymssql 1.0.2

Thanks, again!

- Luke

On Wed, Oct 14, 2009 at 6:46 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 Luke Arno wrote:
  So, is there any chance that relations across multiple _logical_
  databases on a _single_ physical server will be supported by
  SQLAlchemy in the future?

 that is supported now, via the schema argument to Table, assuming you
 are connecting with an account that has access to all logical databases.

 relation() supports spanning physical databases as well, if you either
 ensure the secondary table is on the same server as the target, or
 alternatively map the association table explicitly as I said in my initial
 response.






 
  Thanks.
 
  - Luke
 
  On Wed, Oct 14, 2009 at 3:01 PM, Luke Arno luke.a...@gmail.com wrote:
 
  Thanks, Simon. Good suggestion, but these are databases and not
  schema within a database. If I use the schema=MyDatabase. (
  notice the .) and quote_schema=False, the table names come out
  like I want, but look at what happens to the label here:
 
  SELECT [LeftTable_1].description AS [MyDatabase._LeftTab_1]
  FROM MyDatabase..[LeftTable] AS [LeftTable_1]
  WHERE [LeftTable_1].id = %(param_1)s
 
  That is really abusing the schema feature, so this is not a bug... I
  just wish there were a databasename=Foo option for Table() so I
  could use these ugly databases the way they are. :(
 
 
  On Wed, Oct 14, 2009 at 11:51 AM, King Simon-NFHD78 
  simon.k...@motorola.com wrote:
 
 
   -Original Message-
   From: sqlalchemy@googlegroups.com
   [mailto:sqlalch...@googlegroups.com] On Behalf Of Luke Arno
   Sent: 14 October 2009 16:41
   To: sqlalchemy@googlegroups.com
   Subject: [sqlalchemy] Re: ORM Many to Many Across Two Databases
  
   It looks like if I put the relation on the obj mapped to the DB where
   the association table is _not_, it works in one direction.
   (So, in the
   example Right.lefts can work but Left.rights cannot.) When trying to
   use Left.rights, it looks for the table in the wrong database.
  
   It appears that it would be fine if I could just get the
   table names all
   qualified with database name in the issued SQL. Is there a way to
   make that happen, by any chance?
  
 
  You can do this by using a single engine and metadata, and passing a
  'schema' parameter when defining your tables:
 
 
 http://www.sqlalchemy.org/docs/05/metadata.html#specifying-the-schema-na
  me
 
  Hope that helps,
 
  Simon

[sqlalchemy] Re: ORM Many to Many Across Two Databases

2009-10-14 Thread Michael Bayer

Luke Arno wrote:
 I have a MSSQL server with two logical databases. (I inherited this
 situation,
 of course.) There is a table in each database and an association table in
 one of them. What is the right way to configure this? Here is what I have
 and
 it complains about the values in foreign_keys. I've tried a lot of
 permutations
 and can't seem to hit on the right one. Thanks much!

 left_engine = create_engine(SERVER_A_DB_ONE)
 left_meta = MetaData()
 left_meta.bind = left_engine

 right_engine = create_engine(SERVER_A_DB_TWO)
 right_meta = MetaData()
 right_meta.bind = right_engine

 left_table = Table('LeftTable', left_meta,
 Column('id', Integer, primary_key=True),
 Column('description', String(128)))

 right_table = Table('RightTable', right_meta,
 Column('id', Integer, primary_key=True),
 Column('description', String(128)))

 assoc_table = Table('LeftAssoc', left_meta,
 Column('left_id', Integer),
 Column('right_id', Integer))

 MySession = sessionmaker(binds={
 left_table: left_engine,
 right_table: right_engine,
 assoc_table: left_engine
 })

 class Left(object): pass

 class Right(object): pass

 mapper(Left, left_table)

 mapper(Right, right_table, properties={
 'lefts': relation(Left, secondary=assoc_table,
 primaryjoin=right_table.c.id==assoc_table.c.right_id,
 secondaryjoin=assoc_table.c.left_id==left_table.c.id,
 foreign_keys=[right_table.c.id, left_table.c.id],
 backref=rights),
 })


the foreign keys here would be assoc_table.c.left_id and
assoc_table.c.right_id.

However I don't think relation() + secondary is going to work here.  The
load of child objects will be against the target database only - there's
no behavior such that it will separately select rows from the association
table first, then the target table.

Your two options here are to map assoc_table explicitly, optionally using
association_proxy to have its usage be implicit, or alternately to build a
read-only accessor on your class which manually queries the association
table and then queries the target table.

Another possibility, if this were Oracle I'd suggest using dblink tables
- tables which are present in the local database but are remote to
another server.   Since MS-SQL competes fiercely with Oracle I wouldn't be
surprised if MS-SQL supports such a concept as well.




 - Luke

 



--~--~-~--~~~---~--~~
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: ORM Many to Many Across Two Databases

2009-10-14 Thread King Simon-NFHD78

 -Original Message-
 From: sqlalchemy@googlegroups.com 
 [mailto:sqlalch...@googlegroups.com] On Behalf Of Luke Arno
 Sent: 14 October 2009 16:41
 To: sqlalchemy@googlegroups.com
 Subject: [sqlalchemy] Re: ORM Many to Many Across Two Databases
 
 It looks like if I put the relation on the obj mapped to the DB where 
 the association table is _not_, it works in one direction. 
 (So, in the 
 example Right.lefts can work but Left.rights cannot.) When trying to 
 use Left.rights, it looks for the table in the wrong database.
 
 It appears that it would be fine if I could just get the 
 table names all
 qualified with database name in the issued SQL. Is there a way to 
 make that happen, by any chance?
 

You can do this by using a single engine and metadata, and passing a
'schema' parameter when defining your tables:

http://www.sqlalchemy.org/docs/05/metadata.html#specifying-the-schema-na
me

Hope that helps,

Simon

--~--~-~--~~~---~--~~
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: ORM Many to Many Across Two Databases

2009-10-14 Thread Luke Arno
Thanks, Simon. Good suggestion, but these are databases and not
schema within a database. If I use the schema=MyDatabase. (
notice the .) and quote_schema=False, the table names come out
like I want, but look at what happens to the label here:

SELECT [LeftTable_1].description AS [MyDatabase._LeftTab_1]
FROM MyDatabase..[LeftTable] AS [LeftTable_1]
WHERE [LeftTable_1].id = %(param_1)s

That is really abusing the schema feature, so this is not a bug... I
just wish there were a databasename=Foo option for Table() so I
could use these ugly databases the way they are. :(

On Wed, Oct 14, 2009 at 11:51 AM, King Simon-NFHD78 simon.k...@motorola.com
 wrote:


  -Original Message-
  From: sqlalchemy@googlegroups.com
  [mailto:sqlalch...@googlegroups.com] On Behalf Of Luke Arno
  Sent: 14 October 2009 16:41
  To: sqlalchemy@googlegroups.com
  Subject: [sqlalchemy] Re: ORM Many to Many Across Two Databases
 
  It looks like if I put the relation on the obj mapped to the DB where
  the association table is _not_, it works in one direction.
  (So, in the
  example Right.lefts can work but Left.rights cannot.) When trying to
  use Left.rights, it looks for the table in the wrong database.
 
  It appears that it would be fine if I could just get the
  table names all
  qualified with database name in the issued SQL. Is there a way to
  make that happen, by any chance?
 

 You can do this by using a single engine and metadata, and passing a
 'schema' parameter when defining your tables:

 http://www.sqlalchemy.org/docs/05/metadata.html#specifying-the-schema-na
 me

 Hope that helps,

 Simon

 


--~--~-~--~~~---~--~~
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: ORM Many to Many Across Two Databases

2009-10-14 Thread Luke Arno
So, is there any chance that relations across multiple _logical_
databases on a _single_ physical server will be supported by
SQLAlchemy in the future?

As I mentioned before, this could work (at least for MSSQL)
if we only had a databasename=foo on Table(). I am not
really sure how much work it would be, but it _sounds_ easy. :)

Thanks.

- Luke

On Wed, Oct 14, 2009 at 3:01 PM, Luke Arno luke.a...@gmail.com wrote:

 Thanks, Simon. Good suggestion, but these are databases and not
 schema within a database. If I use the schema=MyDatabase. (
 notice the .) and quote_schema=False, the table names come out
 like I want, but look at what happens to the label here:

 SELECT [LeftTable_1].description AS [MyDatabase._LeftTab_1]
 FROM MyDatabase..[LeftTable] AS [LeftTable_1]
 WHERE [LeftTable_1].id = %(param_1)s

 That is really abusing the schema feature, so this is not a bug... I
 just wish there were a databasename=Foo option for Table() so I
 could use these ugly databases the way they are. :(


 On Wed, Oct 14, 2009 at 11:51 AM, King Simon-NFHD78 
 simon.k...@motorola.com wrote:


  -Original Message-
  From: sqlalchemy@googlegroups.com
  [mailto:sqlalch...@googlegroups.com] On Behalf Of Luke Arno
  Sent: 14 October 2009 16:41
  To: sqlalchemy@googlegroups.com
  Subject: [sqlalchemy] Re: ORM Many to Many Across Two Databases
 
  It looks like if I put the relation on the obj mapped to the DB where
  the association table is _not_, it works in one direction.
  (So, in the
  example Right.lefts can work but Left.rights cannot.) When trying to
  use Left.rights, it looks for the table in the wrong database.
 
  It appears that it would be fine if I could just get the
  table names all
  qualified with database name in the issued SQL. Is there a way to
  make that happen, by any chance?
 

 You can do this by using a single engine and metadata, and passing a
 'schema' parameter when defining your tables:

 http://www.sqlalchemy.org/docs/05/metadata.html#specifying-the-schema-na
 me

 Hope that helps,

 Simon

 



--~--~-~--~~~---~--~~
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: ORM Many to Many Across Two Databases

2009-10-14 Thread Michael Bayer

Luke Arno wrote:
 So, is there any chance that relations across multiple _logical_
 databases on a _single_ physical server will be supported by
 SQLAlchemy in the future?

that is supported now, via the schema argument to Table, assuming you
are connecting with an account that has access to all logical databases.

relation() supports spanning physical databases as well, if you either
ensure the secondary table is on the same server as the target, or
alternatively map the association table explicitly as I said in my initial
response.







 Thanks.

 - Luke

 On Wed, Oct 14, 2009 at 3:01 PM, Luke Arno luke.a...@gmail.com wrote:

 Thanks, Simon. Good suggestion, but these are databases and not
 schema within a database. If I use the schema=MyDatabase. (
 notice the .) and quote_schema=False, the table names come out
 like I want, but look at what happens to the label here:

 SELECT [LeftTable_1].description AS [MyDatabase._LeftTab_1]
 FROM MyDatabase..[LeftTable] AS [LeftTable_1]
 WHERE [LeftTable_1].id = %(param_1)s

 That is really abusing the schema feature, so this is not a bug... I
 just wish there were a databasename=Foo option for Table() so I
 could use these ugly databases the way they are. :(


 On Wed, Oct 14, 2009 at 11:51 AM, King Simon-NFHD78 
 simon.k...@motorola.com wrote:


  -Original Message-
  From: sqlalchemy@googlegroups.com
  [mailto:sqlalch...@googlegroups.com] On Behalf Of Luke Arno
  Sent: 14 October 2009 16:41
  To: sqlalchemy@googlegroups.com
  Subject: [sqlalchemy] Re: ORM Many to Many Across Two Databases
 
  It looks like if I put the relation on the obj mapped to the DB where
  the association table is _not_, it works in one direction.
  (So, in the
  example Right.lefts can work but Left.rights cannot.) When trying to
  use Left.rights, it looks for the table in the wrong database.
 
  It appears that it would be fine if I could just get the
  table names all
  qualified with database name in the issued SQL. Is there a way to
  make that happen, by any chance?
 

 You can do this by using a single engine and metadata, and passing a
 'schema' parameter when defining your tables:

 http://www.sqlalchemy.org/docs/05/metadata.html#specifying-the-schema-na
 me

 Hope that helps,

 Simon

 



 



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