[sqlalchemy] No attribute of child relation contained in parent object

2011-01-26 Thread cornelinux
Hi,

I am just starting to use the relation between two tables.
The problem started with the child data not being written to the child
tables.
I played around, and now I am totally confused.
Maybe someone can shed some light on this.

I got these tables:

{{{
user_table = sa.Table('User', meta.metadata,
sa.Column('UserId',  sa.types.Integer(),
primary_key=True),
sa.Column('UserDesc',sa.types.UnicodeText(),
default=u''),
)

userrealm_table = sa.Table('UserRealm', meta.metadata,
sa.Column('id', sa.types.Integer(), primary_key=True),
sa.Column('user_id',
sa.types.Integer(),ForeignKey('User.UserId')),
sa.Column('realm_id', sa.types.Integer(),
nullable=False )
)
}}}

I got the following classes:

{{{
class User(object):
def __init__(self,  desc):
log.debug(' __init__(%s)' % desc)
self.UserDesc = serial

classe UserRealm(object):
def __init__(self, realm):
log.debug(setting realm_id to %i % realm)
self.realm_id = realm
}}}

A user may belong to several realms. All the relation stuff should be
done in the mappers:

{{{
orm.mapper(UserRealm, userrealm_table)
orm.mapper(User, user_table, properties={
'children':relationship(UserRealm,backref='user', cascade=save-
update)
})
}}}

Now I am at the point, that the User object contains no attribute
identifying the realm...
I thought this attribute should be generated by the relation
definition?

Any ideas on this?

Kind regards
Cornelius

-- 
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] Complex query (for me)

2011-01-26 Thread Enrico Morelli
Dear all,

I've a situation where some tutors has some doctorates. Each doctorate
has to upload some reports. Each tutor has to approve reports of his
doctorates.

These are the tables and mappers:

members_table = Table('members', metadata,
Column('id', types.Integer, primary_key=True),
Column('lastname', types.Unicode(30), nullable=False),
Column('tutor_id', types.Integer, ForeignKey('members.id'),
nullable=True),
Column('removed', types.Boolean, default=False))

reports_table = Table('reports', metadata,
Column('id', types.Integer, primary_key=True),
Column('approved', types.Boolean, default=False),
Column('writer', types.Integer, ForeignKey('members.id'),
nullable=False))

mapper(Members, members_table,
   properties={
   'tutor': relation(Members, backref='doctorate',
 remote_side=members_table.c.id) 
   })

mapper(Reports, reports_table,
properties={
'owner': relation(Members, backref='report')
})

I have to create a query to select all reports of all doctorates of a
tutor. Using the following query I'm able to have all doctorate of a
tutor. 
result = Session.query(Members).filter(and_(Members.removed==False,
Members.tutor.has(Members.id==tutor_id))).all()

But I'm not able to select also the doctorate reports.

Thanks
-- 
---
   (o_
(o_//\  Coltivate Linux che tanto Windows si pianta da solo.
(/)_   V_/_
+--+
| ENRICO MORELLI |  email: more...@cerm.unifi.it   |
| * *   *   *|  phone: +39 055 4574269 |
|  University of Florence|  fax  : +39 055 4574253 |
|  CERM - via Sacconi, 6 -  50019 Sesto Fiorentino (FI) - ITALY|
+--+

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



Re: [sqlalchemy] Complex query (for me)

2011-01-26 Thread Enrico Morelli
For the moment I solved using these query:

doctorate = Session.query(Members).filter(and_(Members.removed==False,
Members.tutor.has(id=tutor_id))).subquery()
reports = Session.query(Reports, doctorate.c.id).outerjoin((doctorate,
Reports.writer==doctorate.c.id)).order_by(Reports.id).all()
# Only to obtain the objects related to the tutor
reports = [reports[i][0] for i in range(len(reports)) if reports[i][1]]

Are there other possibilities?

Thanks
-- 
---
   (o_
(o_//\  Coltivate Linux che tanto Windows si pianta da solo.
(/)_   V_/_
+--+
| ENRICO MORELLI |  email: more...@cerm.unifi.it   |
| * *   *   *|  phone: +39 055 4574269 |
|  University of Florence|  fax  : +39 055 4574253 |
|  CERM - via Sacconi, 6 -  50019 Sesto Fiorentino (FI) - ITALY|
+--+

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



Re: [sqlalchemy] No attribute of child relation contained in parent object

2011-01-26 Thread Cornelius Kölbel
Hi List,

ok, i figured it out. My understanding of the documentation was a bit
different.
I really worked out this way. But

Thekey in the properties is the attribute name, that will be added to
the parent object.
So doing this

orm.mapper(User, user_table, properties={
'realms':relation(TokenRealm, backref=backref('user')
)

...will add an attribute User.realms.

Kind regards
Cornelius

Am 26.01.2011 11:45, schrieb cornelinux:
 Hi,

 I am just starting to use the relation between two tables.
 The problem started with the child data not being written to the child
 tables.
 I played around, and now I am totally confused.
 Maybe someone can shed some light on this.

 I got these tables:

 {{{
 user_table = sa.Table('User', meta.metadata,
 sa.Column('UserId',  sa.types.Integer(),
 primary_key=True),
 sa.Column('UserDesc',sa.types.UnicodeText(),
 default=u''),
 )

 userrealm_table = sa.Table('UserRealm', meta.metadata,
 sa.Column('id', sa.types.Integer(), primary_key=True),
 sa.Column('user_id',
 sa.types.Integer(),ForeignKey('User.UserId')),
 sa.Column('realm_id', sa.types.Integer(),
 nullable=False )
 )
 }}}

 I got the following classes:

 {{{
 class User(object):
 def __init__(self,  desc):
 log.debug(' __init__(%s)' % desc)
 self.UserDesc = serial

 classe UserRealm(object):
 def __init__(self, realm):
 log.debug(setting realm_id to %i % realm)
 self.realm_id = realm
 }}}

 A user may belong to several realms. All the relation stuff should be
 done in the mappers:

 {{{
 orm.mapper(UserRealm, userrealm_table)
 orm.mapper(User, user_table, properties={
 'children':relationship(UserRealm,backref='user', cascade=save-
 update)
 })
 }}}

 Now I am at the point, that the User object contains no attribute
 identifying the realm...
 I thought this attribute should be generated by the relation
 definition?

 Any ideas on this?

 Kind regards
 Cornelius





signature.asc
Description: OpenPGP digital signature


[sqlalchemy] outerjoin

2011-01-26 Thread Pankaj
Hi,

I have this subquery, which yields results

sp_HeaderDetails =
session.query( InvoiceCashFlowPerDocNum.sequence_id,
InvoiceHeaderInfo.invoice_ref, InvoiceHeaderInfo.doc_num  ) \
.filter( ( InvoiceCashFlowPerDocNum.doc_num ==
InvoiceHeaderInfo.doc_num ) )  \
.subquery()

I then do a outerjoin on another query

cashflows = session.query( CashflowEventDetail, sp_HeaderDetails ) \
   .outerjoin( ( sp_HeaderDetails,
and_(sp_HeaderDetails.c.sequence_id ==
CashflowEventDetail.sequence_id ) ) )

This above statement generates the following sql:


SELECT cash_flow_event_detail.id
FROM cash_flow_event_detail LEFT OUTER JOIN (SELECT
invoice_cashflows.sequence_id AS sequence_id,
invoice_header_information.invoice_ref AS invoice_ref,
invoice_header_information.doc_num AS doc_num
FROM invoice_cashflows, invoice_header_information
WHERE invoice_cashflows.doc_num = invoice_header_information.doc_num)
AS anon_1 ON anon_1.sequence_id = cash_flow_event_detail.sequence_id

The above sql doesnt return any values if I run the sql in python. It
also generates error when I run it in db artisan generating a missing
keyword error.

However, if I remove the keyword AS in clause AS anon_1, it
succeeds in DbArtisan.

Any help would be appreciated

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



Re: [sqlalchemy] outerjoin

2011-01-26 Thread Michael Bayer

On Jan 26, 2011, at 11:46 AM, Pankaj wrote:

 Hi,
 
 I have this subquery, which yields results
 
 sp_HeaderDetails =
 session.query( InvoiceCashFlowPerDocNum.sequence_id,
 InvoiceHeaderInfo.invoice_ref, InvoiceHeaderInfo.doc_num  ) \
.filter( ( InvoiceCashFlowPerDocNum.doc_num ==
 InvoiceHeaderInfo.doc_num ) )  \
.subquery()
 
 I then do a outerjoin on another query
 
 cashflows = session.query( CashflowEventDetail, sp_HeaderDetails ) \
   .outerjoin( ( sp_HeaderDetails,
 and_(sp_HeaderDetails.c.sequence_id ==
 CashflowEventDetail.sequence_id ) ) )



 
 This above statement generates the following sql:
 
 
 SELECT cash_flow_event_detail.id
 FROM cash_flow_event_detail LEFT OUTER JOIN (SELECT
 invoice_cashflows.sequence_id AS sequence_id,
 invoice_header_information.invoice_ref AS invoice_ref,
 invoice_header_information.doc_num AS doc_num
 FROM invoice_cashflows, invoice_header_information
 WHERE invoice_cashflows.doc_num = invoice_header_information.doc_num)
 AS anon_1 ON anon_1.sequence_id = cash_flow_event_detail.sequence_id

This doesn't make sense, your query has two different selectables passed to 
query() so should have at least all the columns from sp_HeaderDetails listed 
out in the columns clause, unless you're paraphrasing.   The SQL is otherwise 
correct, unless you're on a platform such as Oracle which does not generate the 
AS keyword.   SQLAlchemy does not generate AS when the statement is 
compiled against such a backend.   If this is not the case, would need DB in 
use, version information, test case.


-- 
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] simple update without a session or mapping

2011-01-26 Thread Josh Stratton
I'm currently interfacing with an Oracle db using sqlalchemy without
any sessions or mappings.  Selects and inserts work great, but I'd
like to be able to update a row without having to delete and reinsert
it.

# remove the id
table.delete(table.c.id == row['id']).execute()

# add it back with new value
row['name'] = 'now frank'
self.conn.execute(table.insert(), row)

I realize there there's an update function in table, but I'm at a loss
as to how to use the syntax for it.  I'm just changing one or two
non-primary-key values.  All the examples I see use the ORM mappings
with sessions, or use the update to change every field in a column.

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



Re: [sqlalchemy] simple update without a session or mapping

2011-01-26 Thread Michael Bayer
the docs for update() are at:

tutorial: http://www.sqlalchemy.org/docs/core/tutorial.html#inserts-and-updates
API: 
http://www.sqlalchemy.org/docs/core/expression_api.html#sqlalchemy.sql.expression.update


On Jan 26, 2011, at 2:14 PM, Josh Stratton wrote:

 I'm currently interfacing with an Oracle db using sqlalchemy without
 any sessions or mappings.  Selects and inserts work great, but I'd
 like to be able to update a row without having to delete and reinsert
 it.
 
# remove the id
table.delete(table.c.id == row['id']).execute()
 
# add it back with new value
row['name'] = 'now frank'
self.conn.execute(table.insert(), row)
 
 I realize there there's an update function in table, but I'm at a loss
 as to how to use the syntax for it.  I'm just changing one or two
 non-primary-key values.  All the examples I see use the ORM mappings
 with sessions, or use the update to change every field in a column.
 
 -- 
 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.
 

-- 
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] autocommit on for DDL

2011-01-26 Thread A.M.
Hello,

While working on a database test with nose, I dug into sqlalchemy 0.6.6 until I 
found these lines:

class DDLElement(expression.Executable, expression.ClauseElement):
Base class for DDL expression constructs.

_execution_options = expression.Executable.\
_execution_options.union({'autocommit':True})

In my nose test against postgresql, I emit a bunch of DDL, perform the test and 
then roll back the whole shebang which conveniently makes it look like I didn't 
touch the database. Obviously, the emitted commits were getting in my way, so I 
wrote this:

class NoCommitDDL(DDL):
def __init__(self,*args,**kw):
super(NoCommitDDL,self).__init__(*args,**kw)
unfrozen = dict(self._execution_options)
del unfrozen['autocommit']
self._execution_options = frozendict(unfrozen)

DDL = NoCommitDDL

I still feel like I am missing something though. I understand that PostgreSQL 
is perhaps one of few databases to allow for transaction-aware DDL, but why is 
a commit emitted for the DDL for any database, when the database makes it 
implied anyway?

Thanks.

Cheers,
M

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



Re: [sqlalchemy] autocommit on for DDL

2011-01-26 Thread Michael Bayer

On Jan 26, 2011, at 5:16 PM, A.M. wrote:

 Hello,
 
 While working on a database test with nose, I dug into sqlalchemy 0.6.6 until 
 I found these lines:
 
 class DDLElement(expression.Executable, expression.ClauseElement):
Base class for DDL expression constructs.
 
_execution_options = expression.Executable.\
_execution_options.union({'autocommit':True})
 
 In my nose test against postgresql, I emit a bunch of DDL, perform the test 
 and then roll back the whole shebang which conveniently makes it look like I 
 didn't touch the database. Obviously, the emitted commits were getting in my 
 way, so I wrote this:
 
 class NoCommitDDL(DDL):
def __init__(self,*args,**kw):
super(NoCommitDDL,self).__init__(*args,**kw)
unfrozen = dict(self._execution_options)
del unfrozen['autocommit']
self._execution_options = frozendict(unfrozen)
 
 DDL = NoCommitDDL
 
 I still feel like I am missing something though. I understand that PostgreSQL 
 is perhaps one of few databases to allow for transaction-aware DDL, but why 
 is a commit emitted for the DDL for any database, when the database makes it 
 implied anyway?

Several databases offer transactional DDL including Postgresql.SQLA doesn't 
differentiate between these backends - it emits COMMIT after any statement that 
it considers to be an autocommit statement.  autocommit means, commit this 
statement after completion, if a transaction is not in progress.

From this it follows that if you'd like to emit several DDL statements in a 
transaction, the usage is no different for DDL expressions than for any other 
kind of DML statement (i.e insert/update/delete).   Use 
connection.begin()/transaction.commit() as documented at:

http://www.sqlalchemy.org/docs/core/connections.html#using-transactions 
.

autocommit is described right after that:


http://www.sqlalchemy.org/docs/core/connections.html#understanding-autocommit

Also the public API for _execution_options is the execution_options() 
generative call: 


http://www.sqlalchemy.org/docs/core/expression_api.html?highlight=execution_options#sqlalchemy.sql.expression.Executable.execution_options
 .

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



Re: [sqlalchemy] autocommit on for DDL

2011-01-26 Thread A.M.

On Jan 26, 2011, at 5:45 PM, Michael Bayer wrote:
 
 
 From this it follows that if you'd like to emit several DDL statements in a 
 transaction, the usage is no different for DDL expressions than for any other 
 kind of DML statement (i.e insert/update/delete).   Use 
 connection.begin()/transaction.commit() as documented at:
 
   http://www.sqlalchemy.org/docs/core/connections.html#using-transactions 
 .
 
 autocommit is described right after that:
 
   
 http://www.sqlalchemy.org/docs/core/connections.html#understanding-autocommit
 
 Also the public API for _execution_options is the execution_options() 
 generative call: 
 
   
 http://www.sqlalchemy.org/docs/core/expression_api.html?highlight=execution_options#sqlalchemy.sql.expression.Executable.execution_options
  .

Thanks for the prodding- I figured out my bug. Here is sample code that 
demonstrates a little surprise. 

First, this code that emits:
BEGIN (implicit)
SELECT 1
ROLLBACK

=
from sqlalchemy.engine import create_engine
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.orm import scoped_session
from sqlalchemy.schema import DDL

engine = create_engine('postgresql://localhost/test',echo=True)
session = scoped_session(sessionmaker(bind=engine))

DDL(SELECT 1).execute(bind=session)
session.rollback()
=

and here is the buggy code which emits:
SELECT 1
COMMIT

from sqlalchemy.engine import create_engine
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.orm import scoped_session
from sqlalchemy.schema import DDL

engine = create_engine('postgresql://localhost/test',echo=True)
session = scoped_session(sessionmaker(bind=engine))

DDL(SELECT 1).execute(bind=engine)
session.rollback()
=

Can you spot the difference? The DDL in the first code is bound to the session 
and the latter code mistakenly binds to the engine for execution resulting in 
two different execution paths. In hindsight, I guess it makes sense, but it 
certainly was not easy to find...

Cheers,
M

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



Re: [sqlalchemy] autocommit on for DDL

2011-01-26 Thread A.M.
Well, I spoke too soon :( What is the mistake in the following sample code 
which causes the COMMITs to be emitted? Setting autocommit to either True or 
False emits the same SQL. I think this is a case of staring at the same code 
too long causing brain damage- thanks for your patience and help!

from sqlalchemy.engine import create_engine
from sqlalchemy.orm.session import sessionmaker
from sqlalchemy.orm import scoped_session
from sqlalchemy.schema import DDL,MetaData,Table

engine = create_engine('postgresql://localhost/test',echo=True)
session = scoped_session(sessionmaker(bind=engine))
metadata = MetaData()
metadata.bind = engine

Table('test1',metadata)
Table('test2',metadata)
metadata.create_all()

2011-01-26 18:27:48,284 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
version()
2011-01-26 18:27:48,284 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
2011-01-26 18:27:48,286 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
current_schema()
2011-01-26 18:27:48,286 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
2011-01-26 18:27:48,288 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where 
n.nspname=current_schema() and lower(relname)=%(name)s
2011-01-26 18:27:48,288 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {'name': 
u'test1'}
2011-01-26 18:27:48,290 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where 
n.nspname=current_schema() and lower(relname)=%(name)s
2011-01-26 18:27:48,290 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {'name': 
u'test2'}
2011-01-26 18:27:48,291 INFO sqlalchemy.engine.base.Engine.0x...6cd0 
CREATE TABLE test1 (
)


2011-01-26 18:27:48,291 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
2011-01-26 18:27:48,292 INFO sqlalchemy.engine.base.Engine.0x...6cd0 COMMIT
2011-01-26 18:27:48,293 INFO sqlalchemy.engine.base.Engine.0x...6cd0 
CREATE TABLE test2 (
)


2011-01-26 18:27:48,293 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
2011-01-26 18:27:48,294 INFO sqlalchemy.engine.base.Engine.0x...6cd0 COMMIT

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



Re: [sqlalchemy] autocommit on for DDL

2011-01-26 Thread Michael Bayer

On Jan 26, 2011, at 6:10 PM, A.M. wrote:

 
 Thanks for the prodding- I figured out my bug. Here is sample code that 
 demonstrates a little surprise. 
 
 First, this code that emits:
 BEGIN (implicit)
 SELECT 1
 ROLLBACK
 
 =
 from sqlalchemy.engine import create_engine
 from sqlalchemy.orm.session import sessionmaker
 from sqlalchemy.orm import scoped_session
 from sqlalchemy.schema import DDL
 
 engine = create_engine('postgresql://localhost/test',echo=True)
 session = scoped_session(sessionmaker(bind=engine))
 
 DDL(SELECT 1).execute(bind=session)

that's some surprise - a Session was never intended to be used as a bind and 
that argument on DDL.execute() is documented as expecting a Connection or 
Engine.  Its kind of just coincidence it happens to call .execute() on the 
thing it gets and it works.Dynamic typing FTW I guess


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



Re: [sqlalchemy] autocommit on for DDL

2011-01-26 Thread Michael Bayer

On Jan 26, 2011, at 6:32 PM, A.M. wrote:

 Well, I spoke too soon :( What is the mistake in the following sample code 
 which causes the COMMITs to be emitted? Setting autocommit to either True or 
 False emits the same SQL. I think this is a case of staring at the same code 
 too long causing brain damage- thanks for your patience and help!
 
 from sqlalchemy.engine import create_engine
 from sqlalchemy.orm.session import sessionmaker
 from sqlalchemy.orm import scoped_session
 from sqlalchemy.schema import DDL,MetaData,Table
 
 engine = create_engine('postgresql://localhost/test',echo=True)
 session = scoped_session(sessionmaker(bind=engine))
 metadata = MetaData()
 metadata.bind = engine
 
 Table('test1',metadata)
 Table('test2',metadata)
 metadata.create_all()

metadata.create_all() looks at the bind attribute, then uses it to execute 
each DDL statement.   The bind here is an engine so it uses connectionless 
execution.  connectionless execution is usually autocommit as documented here:  
http://www.sqlalchemy.org/docs/core/connections.html#connectionless-execution-implicit-execution

to emit create_all() in a transaction:

conn = engine.connect()
with conn.begin():
metadata.create_all(conn)



 
 2011-01-26 18:27:48,284 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
 version()
 2011-01-26 18:27:48,284 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
 2011-01-26 18:27:48,286 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
 current_schema()
 2011-01-26 18:27:48,286 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
 2011-01-26 18:27:48,288 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
 relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where 
 n.nspname=current_schema() and lower(relname)=%(name)s
 2011-01-26 18:27:48,288 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {'name': 
 u'test1'}
 2011-01-26 18:27:48,290 INFO sqlalchemy.engine.base.Engine.0x...6cd0 select 
 relname from pg_class c join pg_namespace n on n.oid=c.relnamespace where 
 n.nspname=current_schema() and lower(relname)=%(name)s
 2011-01-26 18:27:48,290 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {'name': 
 u'test2'}
 2011-01-26 18:27:48,291 INFO sqlalchemy.engine.base.Engine.0x...6cd0 
 CREATE TABLE test1 (
 )
 
 
 2011-01-26 18:27:48,291 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
 2011-01-26 18:27:48,292 INFO sqlalchemy.engine.base.Engine.0x...6cd0 COMMIT
 2011-01-26 18:27:48,293 INFO sqlalchemy.engine.base.Engine.0x...6cd0 
 CREATE TABLE test2 (
 )
 
 
 2011-01-26 18:27:48,293 INFO sqlalchemy.engine.base.Engine.0x...6cd0 {}
 2011-01-26 18:27:48,294 INFO sqlalchemy.engine.base.Engine.0x...6cd0 COMMIT
 
 -- 
 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.
 

-- 
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] generalized polymorphic mixin

2011-01-26 Thread scott
Is it possible to make a generalized declarative mixin class that
abstracts away all of the syntax of inheritance? I've seen examples
that set up the __mapper_args__ but not the discriminator column, and
examples that set up the discriminator column but not the
__mapper_args__, but none with both.

This is roughly how I imagine it should work, but when I tried this,
rows were created with null values for the discriminator. A full
example is here:
https://gist.github.com/797893

class PolymorphicMixin(object):
@declared_attr
def discriminator(cls):
if Base in cls.__bases__:
return Column('discriminator', types.String(50))
for b in cls.__bases__:
if hasattr(b, 'discriminator'):
return b.discriminator

@declared_attr
def __mapper_args__(cls):
ret = {'polymorphic_identity': cls.__name__}
if Base in cls.__bases__:
ret['polymorphic_on'] = PolymorphicMixin.discriminator
return ret

Thanks,
Scott

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



Re: [sqlalchemy] generalized polymorphic mixin

2011-01-26 Thread Michael Bayer
well it will work if you say this:

class PolymorphicMixin(object):
discriminator = Column('discriminator', types.String(50))
@declared_attr
def __mapper_args__(cls):
ret = {'polymorphic_identity': cls.__name__}
if Base in cls.__bases__:
ret['polymorphic_on'] = cls.discriminator
return ret

This because, when declarative sees a plain Column on a mixin, it makes a copy 
of it for the target class, then takes the step of placing that column into the 
__mapper_args__ dictionary as a replacement for all occurrences of the original 
column.  This is one of the several tricks declarative uses to get mixins to 
work (I was opposed to mixins for a long time for the reason of these tricks 
being necessary).

When using a function to generate Column, it gets called once by declarative, 
once by __mapper_args__(), we then have two Column objects that are totally 
different.  In 0.7 an error message is raised for this condition, I'd imagine 
you tried 0.6 and it silently failed.

However, this approach of discriminator = Column at the class level doesn't 
totally really work, since you'll see that it puts a discriminator column 
on all the subclasses too.   It sort of works out and gets populated on the 
sub-table and all that but we don't really want that.

So we'll instead take advantage of memoizing on the class itself, replacing the 
declared_attr with the column itself, and then it all works:

class PolymorphicMixin(object):
@declared_attr
def discriminator(cls):
if 'discriminator' in cls.__dict__:
return cls.discriminiator
else:
cls.discriminator = d = Column('discriminator', types.String(50))
return d

@declared_attr
def __mapper_args__(cls):
ret = {'polymorphic_identity': cls.__name__}
if Base in cls.__bases__:
ret['polymorphic_on'] = cls.discriminator
return ret


On Jan 26, 2011, at 8:30 PM, scott wrote:

 Is it possible to make a generalized declarative mixin class that
 abstracts away all of the syntax of inheritance? I've seen examples
 that set up the __mapper_args__ but not the discriminator column, and
 examples that set up the discriminator column but not the
 __mapper_args__, but none with both.
 
 This is roughly how I imagine it should work, but when I tried this,
 rows were created with null values for the discriminator. A full
 example is here:
 https://gist.github.com/797893
 
 class PolymorphicMixin(object):
@declared_attr
def discriminator(cls):
if Base in cls.__bases__:
return Column('discriminator', types.String(50))
for b in cls.__bases__:
if hasattr(b, 'discriminator'):
return b.discriminator
 
@declared_attr
def __mapper_args__(cls):
ret = {'polymorphic_identity': cls.__name__}
if Base in cls.__bases__:
ret['polymorphic_on'] = PolymorphicMixin.discriminator
return ret
 
 Thanks,
 Scott
 
 -- 
 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.
 

-- 
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] Multi-get?

2011-01-26 Thread Yang Zhang
Is there something similar to the .get() method in SqlSoup and Session
but which allows me to fetch more than one object by ID, so as to save
on round trips to the DB? (This could be done by composing using the
IN operator in SQL.) Thanks in advance.

-- 
Yang Zhang
http://yz.mit.edu/

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



Re: [sqlalchemy] Multi-get?

2011-01-26 Thread Mike Conley
On Wed, Jan 26, 2011 at 8:17 PM, Yang Zhang yanghates...@gmail.com wrote:

 Is there something similar to the .get() method in SqlSoup and Session
 but which allows me to fetch more than one object by ID, so as to save
 on round trips to the DB? (This could be done by composing using the
 IN operator in SQL.) Thanks in advance.


Did you try something like
   session.query(MyClass).filter(MyClass.id.in_([...list of ids...])).all()


-- 
Mike Conley

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