Re: [sqlalchemy] Serialization / De-serialization for SQLAlchemy Declarative ORM

2018-07-11 Thread Jonathan Vanasco
this looks great, and omfg the docs!

-- 
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] Serialization / De-serialization for SQLAlchemy Declarative ORM

2018-07-11 Thread chris . modzelewski
Hi Mike,

Thanks - I really appreciate it! 

And thanks again for all of the effort you've put into SQLAlchemy! It is a 
"must have" in most of the Python projects I work on these days, and I 
regularly sing its praises to my clients.

All the best,
Chris

On Wednesday, July 11, 2018 at 6:26:55 PM UTC-4, Mike Bayer wrote:
>
> Hi Chris - 
>
> congratulations!   this looks extremely well documented and it's clear 
> you put an enormous amount of effort into it!I will definitely 
> point users your way when they ask for this kind of thing.   Looks 
> great. 
>
> - mike 
>
>
>
> On Wed, Jul 11, 2018 at 4:00 PM,   > wrote: 
> > Hi Folks, 
> > 
> > First off, I'd just like to thank everyone here for all of the awesome 
> work 
> > you've been doing on SQLAlchemy. I've been using the library for years, 
> and 
> > it is a truly fantastic piece of code that I rely on literally every 
> day. 
> > Thank you for all the work that you've done and are doing - it is deeply 
> > appreciated. 
> > 
> > Some time ago, I was thinking about how I might be able to give back to 
> the 
> > SQLAlchemy community, and I realized that I often find myself extending 
> my 
> > SQLAlchemy base models with serialization and de-serialization 
> functionality 
> > (usually to/from JSON and CSV, sometimes YAML or XML). And since it's 
> the 
> > type of thing I've done numerous times in various API and data 
> > science-related projects, I thought it probably makes sense to abstract 
> the 
> > functionality out and package the logic for re-use. 
> > 
> > Separation of concerns being important, I don't think this is 
> functionality 
> > that would be good to build into SQLAlchemy's codebase directly, so 
> instead 
> > I wrote it as a new library I'm calling SQLAthanor which I've just 
> released 
> > to PyPi. 
> > 
> > It works as a drop-in replacement for parts of the SQLAlchemy ORM 
> > (particularly Declarative) that extends models with 
> > serialization/de-serialization support, granting the ability to: 
> > 
> > serialize/de-serialize to/from CSV, JSON, YAML, and Python dict 
> > serialize/de-serialize columns, relationships, hybrid properties, 
> > association proxies, and Python @property attributes 
> > enable/disable serialization for particular attribute/format 
> combinations 
> > execute pre/post-processing functions on inbound/outbound data 
> > 
> > Since this is a new project, v.0.1.0 is only released on PyPi in beta at 
> the 
> > moment. I've got - I think - pretty extensive tests written, but as we 
> all 
> > know, database connectivity is all about edge cases. As it stands, my 
> test 
> > matrix covers Python 2.7, 3.4, 3.5, and 3.6 with versions of SQLAlchemy 
> > going all the way back to 0.9. 
> > 
> > If you're interested, I'd be incredibly grateful for any thoughts, 
> feedback, 
> > suggestions, wish lists, or questions you might have. And (if you do try 
> to 
> > use SQLAthanor in a project) any and all issues you stumble across would 
> > also be incredibly helpful. 
> > 
> > Here are the relevant links if you'd like to take a look: 
> > 
> > DOCUMENTATION: https://sqlathanor.readthedocs.io/en/latest (I hope 
> > comprehensive!) 
> > 
> > PYPI: https://pypi.org/project/sqlathanor/ 
> > 
> > GITHUB: https://github.com/insightindustry/sqlathanor 
> > 
> > Thanks in advance, and I look forward to any thoughts or perspectives 
> you 
> > might have! 
> > 
> > All the best, 
> > Chris 
> > 
> > -- 
> > 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+...@googlegroups.com . 
> > To post to this group, send email to sqlal...@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.


Re: [sqlalchemy] Serialization / De-serialization for SQLAlchemy Declarative ORM

2018-07-11 Thread Mike Bayer
Hi Chris -

congratulations!   this looks extremely well documented and it's clear
you put an enormous amount of effort into it!I will definitely
point users your way when they ask for this kind of thing.   Looks
great.

- mike



On Wed, Jul 11, 2018 at 4:00 PM,   wrote:
> Hi Folks,
>
> First off, I'd just like to thank everyone here for all of the awesome work
> you've been doing on SQLAlchemy. I've been using the library for years, and
> it is a truly fantastic piece of code that I rely on literally every day.
> Thank you for all the work that you've done and are doing - it is deeply
> appreciated.
>
> Some time ago, I was thinking about how I might be able to give back to the
> SQLAlchemy community, and I realized that I often find myself extending my
> SQLAlchemy base models with serialization and de-serialization functionality
> (usually to/from JSON and CSV, sometimes YAML or XML). And since it's the
> type of thing I've done numerous times in various API and data
> science-related projects, I thought it probably makes sense to abstract the
> functionality out and package the logic for re-use.
>
> Separation of concerns being important, I don't think this is functionality
> that would be good to build into SQLAlchemy's codebase directly, so instead
> I wrote it as a new library I'm calling SQLAthanor which I've just released
> to PyPi.
>
> It works as a drop-in replacement for parts of the SQLAlchemy ORM
> (particularly Declarative) that extends models with
> serialization/de-serialization support, granting the ability to:
>
> serialize/de-serialize to/from CSV, JSON, YAML, and Python dict
> serialize/de-serialize columns, relationships, hybrid properties,
> association proxies, and Python @property attributes
> enable/disable serialization for particular attribute/format combinations
> execute pre/post-processing functions on inbound/outbound data
>
> Since this is a new project, v.0.1.0 is only released on PyPi in beta at the
> moment. I've got - I think - pretty extensive tests written, but as we all
> know, database connectivity is all about edge cases. As it stands, my test
> matrix covers Python 2.7, 3.4, 3.5, and 3.6 with versions of SQLAlchemy
> going all the way back to 0.9.
>
> If you're interested, I'd be incredibly grateful for any thoughts, feedback,
> suggestions, wish lists, or questions you might have. And (if you do try to
> use SQLAthanor in a project) any and all issues you stumble across would
> also be incredibly helpful.
>
> Here are the relevant links if you'd like to take a look:
>
> DOCUMENTATION: https://sqlathanor.readthedocs.io/en/latest (I hope
> comprehensive!)
>
> PYPI: https://pypi.org/project/sqlathanor/
>
> GITHUB: https://github.com/insightindustry/sqlathanor
>
> Thanks in advance, and I look forward to any thoughts or perspectives you
> might have!
>
> All the best,
> Chris
>
> --
> 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.


[sqlalchemy] Serialization / De-serialization for SQLAlchemy Declarative ORM

2018-07-11 Thread chris . modzelewski
Hi Folks,

First off, I'd just like to thank everyone here for all of the awesome work 
you've been doing on SQLAlchemy. I've been using the library for years, and 
it is a truly fantastic piece of code that I rely on literally every day. 
Thank you for all the work that you've done and are doing - it is deeply 
appreciated.

Some time ago, I was thinking about how I might be able to give back to the 
SQLAlchemy community, and I realized that I often find myself extending my 
SQLAlchemy base models with serialization and de-serialization 
functionality (usually to/from JSON and CSV, sometimes YAML or XML). And 
since it's the type of thing I've done numerous times in various API and 
data science-related projects, I thought it probably makes sense to 
abstract the functionality out and package the logic for re-use.

Separation of concerns being important, I don't think this is functionality 
that would be good to build into SQLAlchemy's codebase directly, so instead 
I wrote it as a new library I'm calling *SQLAthanor* which I've just 
released to PyPi.

It works as a drop-in replacement for parts of the SQLAlchemy ORM 
(particularly Declarative) that extends models with 
serialization/de-serialization support, granting the ability to:

   - serialize/de-serialize to/from CSV, JSON, YAML, and Python dict
   - serialize/de-serialize columns, relationships, hybrid properties, 
   association proxies, and Python @property attributes
   - enable/disable serialization for particular attribute/format 
   combinations
   - execute pre/post-processing functions on inbound/outbound data

Since this is a new project, *v.0.1.0* is only released on PyPi in beta at 
the moment. I've got - I think - pretty extensive tests written, but as we 
all know, database connectivity is all about edge cases. As it stands, my 
test matrix covers Python 2.7, 3.4, 3.5, and 3.6 with versions of 
SQLAlchemy going all the way back to 0.9.

If you're interested, I'd be incredibly grateful for any thoughts, 
feedback, suggestions, wish lists, or questions you might have. And (if you 
do try to use SQLAthanor in a project) any and all issues you stumble 
across would also be incredibly helpful.

Here are the relevant links if you'd like to take a look:

*DOCUMENTATION:* https://sqlathanor.readthedocs.io/en/latest (I hope 
comprehensive!)

*PYPI: *https://pypi.org/project/sqlathanor/

*GITHUB: *https://github.com/insightindustry/sqlathanor

Thanks in advance, and I look forward to any thoughts or perspectives you 
might have!

All the best,
Chris

-- 
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] Declarative API without state management

2017-11-09 Thread Max Rothman
Thanks for the response!
 

> Is this sort of thing possible? Can the declarative API be used without
>> binding model classes to a session? 
>
>
> The declarative API and the Mapper objects it creates have no 
> dependency on a Session being present at all.   So you're free to 
> build a new kind of Session that doesn't use a unit of work, sure. 
>

So don't use a session at all, or build a new Session class that implements 
the same interface as sqlalchemy's session? Are there particular parts of 
the interface that are depended on by other parts of the system?
   

> I don't really see how this approach is *worth* it, after all if you 
> just session.update(model), what about all the things which refer to 
> it and for which it depends on that may not have been "updated".   You 
> have to hand-wire all that in your code, which would ultimately lead 
> to inventing some new system of automating it all, which means you 
> just reinvent the whole thing.
>

In this design, session.update(model) would return the updated model. In 
theory, the whole point would be to eliminate that non-local behavior and 
move towards a more functional approach. On the other hand, it seems like 
this is one of those ideas that might not hold up in practice. Guess I'll 
have to experiment! 

Decisions made in the name of "separation of 
> concerns", sometimes critical but always very risky. 
>
 
Point taken!
 
Thanks,
Max 

-- 
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] Declarative API without state management

2017-11-02 Thread Mike Bayer
On Thu, Nov 2, 2017 at 3:09 PM, Max Rothman  wrote:
> I was poking around Elixir's Ecto, and I was curious whether it was possible
> to apply their strict separation between data and operations to SQLAlchemy.
> One could imagine an API where session.query fetches mutable, data-only
> versions of models, and models are updated with something like
> session.update(model), which would be a proxy for
> update(Model).where(Model.id == model.id). In that scenario, the only
> stateful element of the session would be the status of the current
> transaction.
>
> Is this sort of thing possible? Can the declarative API be used without
> binding model classes to a session?

The declarative API and the Mapper objects it creates have no
dependency on a Session being present at all.   So you're free to
build a new kind of Session that doesn't use a unit of work, sure.


> Can session state management be turned
> off, or could the connection be used directly?

It depends where you want to make the cutoff.   You can build out this
new ORM using Core where you'd have Connection and all that.  If you
want to still use Query then you'd have to subclass that also and
provide an alternate loading scheme (called from
_execute_and_instances()).

I don't really see how this approach is *worth* it, after all if you
just session.update(model), what about all the things which refer to
it and for which it depends on that may not have been "updated".   You
have to hand-wire all that in your code, which would ultimately lead
to inventing some new system of automating it all, which means you
just reinvent the whole thing.

SQLAlchemy even started with a little bit of this "separation"
idealism, which is why it has this thing nobody uses anymore called
"classical mapping" - the idea that the class definitions would know
nothing about how they are persisted.  Sounds great until you realize
the class needs to refer to its own state and the attributes within
that state are determined by the table schema.   We used to have
querying work as "MyClass.c.col == 'value'", e.g. the ".c." was there
as a means of "separating" the "persistence" from the "object model".
 When we changed it to just be "MyClass.col", the library became
massively easier to use and allowed the whole brilliance of "hybrid
properties" that everyone now loves to come forth.If there were
ever a SQLAlchemy 2, "classical mapping" as an option and
"declarative" as only an "extension" would be at the very top of the
list of things to go.   Decisions made in the name of "separation of
concerns", sometimes critical but always very risky.


>
> Thanks,
> Max
>
> --
> 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.


[sqlalchemy] Declarative API without state management

2017-11-02 Thread Max Rothman
I was poking around Elixir's Ecto , and 
I was curious whether it was possible to apply their strict separation 
between data and operations to SQLAlchemy. One could imagine an API where 
session.query fetches mutable, data-only versions of models, and models are 
updated with something like session.update(model), which would be a proxy 
for update(Model).where(Model.id == model.id). In that scenario, the only 
stateful element of the session would be the status of the current 
transaction.

Is this sort of thing possible? Can the declarative API be used without 
binding model classes to a session? Can session state management be turned 
off, or could the connection be used directly?

Thanks,
Max

-- 
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] declarative Association table w/ foreign_keys in relationship() still raises "multiple foreign key paths linking the tables"

2016-12-09 Thread bkc
That's a good suggestion, thanks.

-- 
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] declarative Association table w/ foreign_keys in relationship() still raises "multiple foreign key paths linking the tables"

2016-12-09 Thread mike bayer

leader/follower is often used in this case.


On 12/09/2016 10:33 AM, b...@sfi.ca wrote:

Thanks Mike for the quick reply.

I have changed the code so it uses backref on one side. The models now
get created w/o error. I haven't actually tested using the relationship
but I'm sure it's fine now.

For anyone else with this problem, here's the 'fixed' code. I didn't
change the Artifact_Reference table, it's the same as posted above. I'm
not keen on the naming master/slave.. maybe primary/secondary would be
better.. It's not exactly Parent/Child.. heh.


|
class Artifact_Relation(Base):
__tablename__ = 'artifact_relation'
master_artifact_id = Column(
Integer,
ForeignKey('artifact.id', name='artifact_relation_master_id_fk',
ondelete="cascade", onupdate="cascade"),
primary_key=True,
nullable=False
)

slave_artifact_id = Column(
Integer,
ForeignKey('artifact.id', name='artifact_relation_slave_id_fk',
ondelete="cascade", onupdate="cascade"),
primary_key=True,
nullable=False
)

relationship_type = Column(String(24), nullable=False)

slave = relationship("Artifact", backref=backref("masters"),
foreign_keys=[slave_artifact_id])
master = relationship("Artifact", backref=backref("slaves"),
foreign_keys=[master_artifact_id])

class Artifact(Base):
"Artifact"
__tablename__ = 'artifact'
id = Column('id', Integer, primary_key=True)
artifact_type = Column('artifact_type', String(16), nullable=False)
__mapper_args__ = {
'polymorphic_on': artifact_type
}

artifact_references = relationship(
'Artifact_Reference',
back_populates='artifact',
cascade="all, delete-orphan",
passive_deletes=True
)

|


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


Re: [sqlalchemy] declarative Association table w/ foreign_keys in relationship() still raises "multiple foreign key paths linking the tables"

2016-12-09 Thread bkc
Thanks Mike for the quick reply.

I have changed the code so it uses backref on one side. The models now get 
created w/o error. I haven't actually tested using the relationship but I'm 
sure it's fine now.

For anyone else with this problem, here's the 'fixed' code. I didn't change 
the Artifact_Reference table, it's the same as posted above. I'm not keen 
on the naming master/slave.. maybe primary/secondary would be better.. It's 
not exactly Parent/Child.. heh.


class Artifact_Relation(Base):
__tablename__ = 'artifact_relation'
master_artifact_id = Column(
Integer,
ForeignKey('artifact.id', name='artifact_relation_master_id_fk', 
ondelete="cascade", onupdate="cascade"),
primary_key=True,
nullable=False
)

slave_artifact_id = Column(
Integer,
ForeignKey('artifact.id', name='artifact_relation_slave_id_fk', 
ondelete="cascade", onupdate="cascade"),
primary_key=True,
nullable=False
)

relationship_type = Column(String(24), nullable=False)

slave = relationship("Artifact", backref=backref("masters"), 
foreign_keys=[slave_artifact_id])
master = relationship("Artifact", backref=backref("slaves"), 
foreign_keys=[master_artifact_id])

class Artifact(Base):
"Artifact"
__tablename__ = 'artifact'
id = Column('id', Integer, primary_key=True)
artifact_type = Column('artifact_type', String(16), nullable=False)
__mapper_args__ = {
'polymorphic_on': artifact_type
}

artifact_references = relationship(
'Artifact_Reference',
back_populates='artifact',
cascade="all, delete-orphan",
passive_deletes=True
)



-- 
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] declarative Association table w/ foreign_keys in relationship() still raises "multiple foreign key paths linking the tables"

2016-12-08 Thread bkc
Hi,

Running SQLAlchemy==1.1.4

I'm getting this

AmbiguousForeignKeysError: Could not determine join condition between 
> parent/child tables on relationship Artifact.slaves - there are multiple 
> foreign key paths linking the tables.  Specify the 'foreign_keys' argument, 
> providing a list of those columns which should be counted as containing a 
> foreign key reference to the parent table.
>

and I'm wondering if I'll have to use primaryjoin= statement instead of 
relying on foreign_keys= to work around this.

The code is shown below. I've included Artifact_Reference for completeness 
but it's probably not needed.

Is the problem on the Artifact_Relation model, or on the Artifact model? 
I'm thinking the later, but I don't see any logical way to specify 
foreign_keys on Artifact as it's on the one side of many to one. 

I'm following this link for Artifact_Relation (i.e. Association 
table) 
http://docs.sqlalchemy.org/en/latest/orm/basic_relationships.html#association-object
 
 where Artifact serves as both the Parent and Child

I'm following this link for multiple-path 
resolution 
http://docs.sqlalchemy.org/en/latest/orm/join_conditions.html#relationship-foreign-keys

Even though Artifact is on both sides of the association, I can't see 
needing to use backref()  w/ remote_id to resolve this, 
ala http://docs.sqlalchemy.org/en/latest/orm/self_referential.html

Thanks for any suggestions..


Base = declarative_base()

class Artifact_Relation(Base):
__tablename__ = 'artifact_relation'
master_artifact_id = Column(
Integer,
ForeignKey('artifact.id', name='artifact_relation_master_id_fk', 
ondelete="cascade", onupdate="cascade"),
primary_key=True,
nullable=False
)

slave_artifact_id = Column(
Integer,
ForeignKey('artifact.id', name='artifact_relation_slave_id_fk', 
ondelete="cascade", onupdate="cascade"),
primary_key=True,
nullable=False
)

relationship_type = Column(String(24), nullable=False)

slave = relationship("Artifact", back_populates="masters", 
foreign_keys=[slave_artifact_id])
master = relationship("Artifact", back_populates="slaves", 
foreign_keys=[master_artifact_id])

class Artifact(Base):
"Artifact"
__tablename__ = 'artifact'
id = Column('id', Integer, primary_key=True)
artifact_type = Column('artifact_type', String(16), nullable=False)
__mapper_args__ = {
'polymorphic_on': artifact_type
}

artifact_references = relationship(
'Artifact_Reference',
back_populates='artifact',
cascade="all, delete-orphan",
passive_deletes=True
)

slaves = relationship("Artifact_Relation", back_populates="master")
masters = relationship("Artifact_Relation", back_populates="slave")

class Artifact_Reference(Base):
"""Artifact_Reference"""
__tablename__ = 'artifact_reference'
id = Column('id', Integer, primary_key=True)
type = Column('type', String(24), nullable=False)
artifact_id = Column('artifact_id', Integer, ForeignKey(Artifact.id, 
name="artifact_reference_artifact_id_fk", ondelete="cascade", 
onupdate="cascade"), nullable=False)
reference = Column('reference', String(64), nullable=False)

artifact = relationship(
Artifact,
back_populates='artifact_references'
)
Index('reference_idx', reference, unique=False)


 


-- 
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] Re: Serializing sqlalchemy declarative instances with yaml

2016-09-20 Thread Sergii Nechuiviter
This is Yaml bug: http://pyyaml.org/ticket/245

-- 
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] Declarative: defining relationship and column in one line

2015-05-31 Thread Mike Bayer



On 5/31/15 6:11 AM, Fayaz Yusuf Khan wrote:

Hi,

On Tuesday, May 19, 2015 at 7:41:45 PM UTC+5:30, Michael Bayer wrote:


http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm/
http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm/

I had tried this one before but it looked like those columns were 
never added to the underlying table.


I just ran the magic.py example from the blog post against SQLA 1.0.4 
and it worked fine.





--
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] Declarative: defining relationship and column in one line

2015-05-31 Thread Fayaz Yusuf Khan
Hi,

On Tuesday, May 19, 2015 at 7:41:45 PM UTC+5:30, Michael Bayer wrote:


 http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm/

 I had tried this one before but it looked like those columns were never 
added to the underlying table.

-- 
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] Declarative: defining relationship and column in one line

2015-05-19 Thread Paul Johnston
Hi,

Sorry if this is a FAQ, but is it possible to define a relationship and its 
column all at once. e.g. instead of:

type_id = db.Column(db.Integer, db.ForeignKey('linktype.id'))
type = db.relationship('LinkType')

Something like:

type = db.relationship('LinkType', colname='type_id')

In fact, it'd be good for the colname to default to xxx_id - although 
allow overriding.

This certainly was possible with Elixir.

Paul

-- 
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] Declarative: defining relationship and column in one line

2015-05-19 Thread Mike Bayer



On 5/19/15 6:54 AM, Paul Johnston wrote:

Hi,

Sorry if this is a FAQ, but is it possible to define a relationship 
and its column all at once. e.g. instead of:


type_id = db.Column(db.Integer, db.ForeignKey('linktype.id'))
type = db.relationship('LinkType')

Something like:

type = db.relationship('LinkType', colname='type_id')

In fact, it'd be good for the colname to default to xxx_id - 
although allow overriding.


This certainly was possible with Elixir.

this would be a many_to_one() macro.  Two examples of this are at:

https://bitbucket.org/zzzeek/pycon2014_atmcraft/src/f50cbe745a197ea7db83569283b703c418481222/atmcraft/model/meta/orm.py?at=master

the above is a modernized improvement on an older example:

http://techspot.zzzeek.org/2011/05/17/magic-a-new-orm/





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


Re: [sqlalchemy] Declarative setup failing on upgrade to 1.0.1

2015-04-25 Thread Bill Schindler
Still getting the same error with 1.0.2.

It's using a custom base class passed to declarative.declarative_base(). 
The class is pretty simple -- mostly just a declared_attr to set the 
__tablename__ and a custom __repr__.

I'll see if I can pare it down to a simple test case.

--
Bill

-- 
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] Declarative setup failing on upgrade to 1.0.1

2015-04-25 Thread Bill Schindler
This may have been an instance of working by accident. In setting up 
declarative_base, we're passing in a mapper function. Our mapper function 
wasn't returning the result of the SA mapper(). It didn't cause any 
(explicit) errors through 0.9.8, but I have a feeling that was just luck.


On Friday, April 24, 2015 at 5:07:58 PM UTC-7, Michael Bayer wrote:

  give 1.0.2 a try since we adjusted some things regarding 
 __declare_first__ and __declare_last__.   Further than that it depends a 
 lot on what your basic Base setup looks like, mixins in use, extensions 
 like AbstractConcreteBase, stuff like that.  Any details you can share 
 would help.




 On 4/24/15 7:02 PM, Bill Schindler wrote:
  
  I'm trying to upgrade from SA 0.9.8 to 1.0.1 and getting a traceback. 
 I'm not sure what's going on here, but the declarative setup is obviously 
 not happy with something. (On 0.9.8, everything runs fine, so I've 
 obviously run afoul of something new/different/fixed.)

File 
 /opt/certwise-lcs/eggs/lcs.content.user-1.0.2dev_r10-py2.7.egg/lcs/content/user/makeorm.py,
  
 line 89, in make_orm
 class Principals(Base):
   File 
 /opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/api.py,
  
 line 55, in __init__
 _as_declarative(cls, classname, cls.__dict__)
   File 
 /opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
  
 line 87, in _as_declarative
 _MapperConfig.setup_mapping(cls, classname, dict_)
   File 
 /opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
  
 line 102, in setup_mapping
 cfg_cls(cls_, classname, dict_)
   File 
 /opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
  
 line 134, in __init__
 self._early_mapping()
   File 
 /opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
  
 line 137, in _early_mapping
 self.map()
   File 
 /opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
  
 line 530, in map
 del mp_.class_manager.info['declared_attr_reg']
 AttributeError: 'NoneType' object has no attribute 'class_manager'
  
  This gets fired off on every ORM class, so I'm guessing the cause is 
 somewhere deeper in our code. Any thoughts on what I might look for to find 
 the cause?

  --
 Bill
  -- 
 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+...@googlegroups.com javascript:.
 To post to this group, send email to sqlal...@googlegroups.com 
 javascript:.
 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] Declarative setup failing on upgrade to 1.0.1

2015-04-24 Thread Bill Schindler
I'm trying to upgrade from SA 0.9.8 to 1.0.1 and getting a traceback. I'm 
not sure what's going on here, but the declarative setup is obviously not 
happy with something. (On 0.9.8, everything runs fine, so I've obviously 
run afoul of something new/different/fixed.)

  File 
/opt/certwise-lcs/eggs/lcs.content.user-1.0.2dev_r10-py2.7.egg/lcs/content/user/makeorm.py,
 
line 89, in make_orm
class Principals(Base):
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/api.py,
 
line 55, in __init__
_as_declarative(cls, classname, cls.__dict__)
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
 
line 87, in _as_declarative
_MapperConfig.setup_mapping(cls, classname, dict_)
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
 
line 102, in setup_mapping
cfg_cls(cls_, classname, dict_)
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
 
line 134, in __init__
self._early_mapping()
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
 
line 137, in _early_mapping
self.map()
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py,
 
line 530, in map
del mp_.class_manager.info['declared_attr_reg']
AttributeError: 'NoneType' object has no attribute 'class_manager'

This gets fired off on every ORM class, so I'm guessing the cause is 
somewhere deeper in our code. Any thoughts on what I might look for to find 
the cause?

--
Bill

-- 
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] Declarative setup failing on upgrade to 1.0.1

2015-04-24 Thread Mike Bayer
give 1.0.2 a try since we adjusted some things regarding 
__declare_first__ and __declare_last__.   Further than that it depends a 
lot on what your basic Base setup looks like, mixins in use, 
extensions like AbstractConcreteBase, stuff like that.  Any details you 
can share would help.





On 4/24/15 7:02 PM, Bill Schindler wrote:
I'm trying to upgrade from SA 0.9.8 to 1.0.1 and getting a traceback. 
I'm not sure what's going on here, but the declarative setup is 
obviously not happy with something. (On 0.9.8, everything runs fine, 
so I've obviously run afoul of something new/different/fixed.)


  File 
/opt/certwise-lcs/eggs/lcs.content.user-1.0.2dev_r10-py2.7.egg/lcs/content/user/makeorm.py, 
line 89, in make_orm

class Principals(Base):
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/api.py, 
line 55, in __init__

_as_declarative(cls, classname, cls.__dict__)
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 87, in _as_declarative

_MapperConfig.setup_mapping(cls, classname, dict_)
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 102, in setup_mapping

cfg_cls(cls_, classname, dict_)
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 134, in __init__

self._early_mapping()
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 137, in _early_mapping

self.map()
  File 
/opt/certwise-lcs/eggs/SQLAlchemy-1.0.1-py2.7-linux-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 530, in map

del mp_.class_manager.info['declared_attr_reg']
AttributeError: 'NoneType' object has no attribute 'class_manager'

This gets fired off on every ORM class, so I'm guessing the cause is 
somewhere deeper in our code. Any thoughts on what I might look for to 
find the cause?


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


Re: [sqlalchemy] Serializing sqlalchemy declarative instances with yaml

2014-10-24 Thread Jonathan Vanasco

Usually for this sort of stuff, I serialize the object's data into a JSON 
dict ( object columns to JSON dict, object relations to a dict, list of 
dicts, or reference to another object).  ( Custom dump/load is needed to 
handle Timestamp, Floats, etc).  You might be able to iterate over the data 
in YAML and not require custom encoding/decoding.  When I need to treat the 
json data as objects, I'll load them into a custom dict class that will 
treat attributes as keys.  

The downside of this is that you don't have all the SqlAlchemy relational 
stuff or any ancillary methods (though they can be bridged in with more 
work).  The benefit though is that you can get a nearly 1:1 parity between 
the core needs without much more work.  When using a read only context, 
you can flip between SqlAlchemy objects and dicts.  If you need to use the 
SqlAlchemy model itself, you could load the column/relationship data into 
it manually.

-- 
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] Serializing sqlalchemy declarative instances with yaml

2014-10-24 Thread Peter Waller
Well I was hoping to just use yaml since yaml understands when two
objects refer to the same underlying object. That means you don't have to
write any logic to de-duplicate objects through relationships, etc.

Since json doesn't have the notion of referencing, that doesn't seem
straightforward there.

I was also hoping to just use yaml to avoid writing custom dumping code,
since it seems in general like a useful capability. So I may yet try and
find the underlying bug and fix it.

On 24 October 2014 15:29, Jonathan Vanasco jvana...@gmail.com wrote:


 Usually for this sort of stuff, I serialize the object's data into a JSON
 dict ( object columns to JSON dict, object relations to a dict, list of
 dicts, or reference to another object).  ( Custom dump/load is needed to
 handle Timestamp, Floats, etc).  You might be able to iterate over the data
 in YAML and not require custom encoding/decoding.  When I need to treat
 the json data as objects, I'll load them into a custom dict class that will
 treat attributes as keys.

 The downside of this is that you don't have all the SqlAlchemy relational
 stuff or any ancillary methods (though they can be bridged in with more
 work).  The benefit though is that you can get a nearly 1:1 parity between
 the core needs without much more work.  When using a read only context,
 you can flip between SqlAlchemy objects and dicts.  If you need to use the
 SqlAlchemy model itself, you could load the column/relationship data into
 it manually.

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


-- 
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] Serializing sqlalchemy declarative instances with yaml

2014-10-24 Thread Jonathan Vanasco

On Friday, October 24, 2014 10:39:43 AM UTC-4, Peter Waller wrote:

 I was also hoping to just use yaml to avoid writing custom dumping code, 
 since it seems in general like a useful capability. So I may yet try and 
 find the underlying bug and fix it.


It might not be a bug, and the effect of an implementation feature of 
SqlAlchemy.  I tried (naively) playing around with your example, and 
thought back to how SqlAlchemy accomplishes much of it's magic by creating 
custom comparators (and other private methods) on the classes and columns.  

Playing around with it, the problem seems to be with the SqlAlchemy 
object's __reduce_ex__ method. If you simply use __reduce__ in yaml, it 
works.  I couldn't figure out what Foo inherits __reduce_ex__ from , or if 
any of the columns have it.

-- 
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] Serializing sqlalchemy declarative instances with yaml

2014-10-24 Thread Peter Waller
The oddity is that calling `__reduce_ex__` on the instance is fine, but on
the class it is not. When serialising a declarative class it finds itself
serialising the class type, which fails. This actually fails for the
`object`, too (see below).

So I think what's happening is that serialisation fails because
`_sa_instance_state`
(somewhere inside it) contains a class. This is probably a yaml bug, then.

In [1]: object().__reduce_ex__(2)
Out[1]: (function copy_reg.__newobj__, (object,), None, None, None)

In [2]: object.__reduce_ex__(2)
---
TypeError Traceback (most recent call last)
ipython-input-1-eebec0cadfee in module()
 1 object.__reduce_ex__(2)

/usr/lib/python2.7/copy_reg.pyc in _reduce_ex(self, proto)
 68 else:
 69 if base is self.__class__:
--- 70 raise TypeError, can't pickle %s objects %
base.__name__
 71 state = base(self)
 72 args = (self.__class__, base, state)

TypeError: can't pickle int objects


On 24 October 2014 17:55, Jonathan Vanasco jvana...@gmail.com wrote:


 On Friday, October 24, 2014 10:39:43 AM UTC-4, Peter Waller wrote:

 I was also hoping to just use yaml to avoid writing custom dumping
 code, since it seems in general like a useful capability. So I may yet try
 and find the underlying bug and fix it.


 It might not be a bug, and the effect of an implementation feature of
 SqlAlchemy.  I tried (naively) playing around with your example, and
 thought back to how SqlAlchemy accomplishes much of it's magic by creating
 custom comparators (and other private methods) on the classes and columns.

 Playing around with it, the problem seems to be with the SqlAlchemy
 object's __reduce_ex__ method. If you simply use __reduce__ in yaml, it
 works.  I couldn't figure out what Foo inherits __reduce_ex__ from , or if
 any of the columns have it.

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


-- 
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] Serializing sqlalchemy declarative instances with yaml

2014-10-23 Thread Michael Bayer

 On Oct 23, 2014, at 7:42 AM, Peter Waller pe...@scraperwiki.com wrote:
 
 We would like to freeze the results of a query to my database in a yaml file, 
 so that we can use the results in an app which isn't connected to the 
 database.
 
 It makes sense here to reuse the model classes. Here's an example:
 
 class Foo(declarative_base()):
 __tablename__ = foo
 id = S.Column(S.Integer, primary_key=True)
 
 Unfortunately, `yaml.dump(Foo())` gives a surprising result:
 
 /usr/lib/python3/dist-packages/yaml/representer.py in represent_object(self, 
 data)
 311 reduce = copyreg.dispatch_table[cls](data)
 312 elif hasattr(data, '__reduce_ex__'):
 -- 313 reduce = data.__reduce_ex__(2)
 314 elif hasattr(data, '__reduce__'):
 315 reduce = data.__reduce__()
 
 /usr/lib/python3.4/copyreg.py in _reduce_ex(self, proto)
  63 else:
  64 if base is self.__class__:
 --- 65 raise TypeError(can't pickle %s objects % base.__name__)
  66 state = base(self)
  67 args = (self.__class__, base, state)
 
 TypeError: can't pickle int objects
 
 It seems that what is happening is that `data` is equal to `Foo`, and 
 `Foo.__reduce_ex__(2)` gives `TypeError: can't pickle int objects`. As does 
 `declarative_base().__reduce_ex__(2)`.
 
 I note that `pickle.dumps` works. But we'd rather use YAML.
 
 Where is the bug? Is it in sqlalchemy, yaml, or python?

no clue.  ints shouldn’t have an issue with pickle, obviously!for Yaml it 
would be much more appropriate to build custom per-class serialization in any 
case since you don’t want all the persistence junk like _sa_instance_state() 
carried along.


-- 
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] declarative polymorphic inheritance abstraction problem

2014-02-10 Thread Chris Withers

Hi All,

I'm trying to be efficient with my code, but it seems to tripping 
SQLAlchemy up.


So, basically I want to have a schema with two tables, content and 
project, to represent two three types of object:


- article has a set of fields as found in the 'content' table
- project has fields that are the set union of the 'content' and 
'project' tables' columns
- content is a plain content type, like article, and will likely never 
be instantiated, but just in case...
- in future, I may want to add more tables/content types where the 
fields are like project; a set union of the 'content' and 'project' 
tables' columns


So, I tried to be clever and start off with the following content 
class/table:


class Content(Base):

content_type = Column(String(20))

@declared_attr
def id(cls):
if cls.__name__=='Content':
return Column(Integer, primary_key=True)
else:
return Column(Integer, ForeignKey('content.id'), 
primary_key=True)


@declared_attr
def __tablename__(cls):
return cls.__name__.lower()

@declared_attr
def __mapper_args__(cls):
args = dict(polymorphic_identity = cls.__name__.lower())
if cls.__name__=='Content':
args['polymorphic_on'] = cls.content_type
return args

...with the following two classes associated with it:

class Article(Content):

@declared_attr
def __tablename__(cls):
return None

class Project(Content):

currency  = Column(String(3))
target = Column(Integer)
current = Column(Integer)

...but I get the following on import:

project.py, line 5, in module
class Project(Content):
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/ext/declarative/api.py, 
line 53, in __init__

_as_declarative(cls, classname, cls.__dict__)
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 322, in _as_declarative

mt.map()
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 405, in map

**mapper_args
  File string, line 2, in mapper
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/orm/mapper.py, 
line 593, in __init__

self._configure_inheritance()
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/orm/mapper.py, 
line 900, in _configure_inheritance

self.local_table)
  File string, line 2, in join_condition
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/sql/selectable.py, 
line 651, in _join_condition

between '%s' and '%s'.%s % (a.description, b.description, hint))
sqlalchemy.exc.NoForeignKeysError: Can't find any foreign key 
relationships between 'content' and 'project'.


If I change the id method to be decorated by classproperty rather than 
declared_attr, the error changes to:


article.py, line 3, in module
from .content import Content
content.py, line 7, in module
class Content(Base):
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/ext/declarative/api.py, 
line 53, in __init__

_as_declarative(cls, classname, cls.__dict__)
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 322, in _as_declarative

mt.map()
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/ext/declarative/base.py, 
line 405, in map

**mapper_args
  File string, line 2, in mapper
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/orm/mapper.py, 
line 599, in __init__

self._configure_pks()
  File 
/Users/chris/buildout-eggs/SQLAlchemy-0.9.1-py2.7-macosx-10.5-x86_64.egg/sqlalchemy/orm/mapper.py, 
line 1189, in _configure_pks

(self, self.mapped_table.description))
sqlalchemy.exc.ArgumentError: Mapper Mapper|Content|content could not 
assemble any primary key columns for mapped table 'content'


What's going wrong here?

cheers,

Chris

--
Simplistix - Content Management, Batch Processing  Python Consulting
- http://www.simplistix.co.uk

--
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/groups/opt_out.


Re: [sqlalchemy] declarative polymorphic inheritance abstraction problem

2014-02-10 Thread Michael Bayer

On Feb 10, 2014, at 2:36 PM, Chris Withers ch...@simplistix.co.uk wrote:

 Hi All,
 
 I'm trying to be efficient with my code, but it seems to tripping SQLAlchemy 
 up.
 
 So, basically I want to have a schema with two tables, content and project, 
 to represent two three types of object:

if you poke around with print statements or pdb, you can see that the “id” 
declared_attr is run only once, for Content.   this is because Content is 
mapped and your “id” declared_attr function is replaced with the mapped 
attribute “id”.

If you make a mixin like HasId and put it there, it still doesn’t work.   
Declarative finds the HasId mixin and the “id” function, but then when it 
resolves what “Project.id” really is, it again just calls getattr() and doesn’t 
call your function.   

Why’s it like that?  I don’t know, but I’m 99% sure at least three tests will 
fail if I change it, lets try:

Code like this:

class HasId(object):
@declared_attr
def id(cls):
if cls.__name__=='Content':
return Column('id', Integer, primary_key=True)
else:
return Column('id', Integer, ForeignKey('content.id'), 
primary_key=True)

class Content(HasId, Base):

content_type = Column(String(20))

@declared_attr
def __tablename__(cls):
return cls.__name__.lower()

class Project(Content):
currency  = Column(String(3))
target = Column(Integer)
current = Column(Integer)

so lets tell declarative to pull off of HasId.id when it scans “Project”, 
instead of getattr(Project, “id”):

--- a/lib/sqlalchemy/ext/declarative/base.py
+++ b/lib/sqlalchemy/ext/declarative/base.py
@@ -126,7 +126,7 @@ def _as_declarative(cls, classname, dict_):
 on declarative mixin classes.)
 elif isinstance(obj, declarative_props):
 dict_[name] = ret = \
-column_copies[obj] = getattr(cls, name)
+column_copies[obj] = getattr(base, name)
 if isinstance(ret, (Column, MapperProperty)) and \
 ret.doc is None:
 ret.doc = obj.__doc__

your test case works, but lets see the tests - six errors and four failures: 
https://gist.github.com/zzzeek/8925277

So we can’t do that.You know I love the mixins/declared_attr thing, but 
it’s hard.  There’s craploads of tests for it and the amount of decisions we’ve 
packed in there is already pretty intricate.

There’s some other variants that reduce the number of test failures, like this:

diff --git a/lib/sqlalchemy/ext/declarative/base.py 
b/lib/sqlalchemy/ext/declarative/base.py
index 4fda9c7..b74809e 100644
--- a/lib/sqlalchemy/ext/declarative/base.py
+++ b/lib/sqlalchemy/ext/declarative/base.py
@@ -126,7 +126,7 @@ def _as_declarative(cls, classname, dict_):
 on declarative mixin classes.)
 elif isinstance(obj, declarative_props):
 dict_[name] = ret = \
-column_copies[obj] = getattr(cls, name)
+column_copies[obj] = obj.__get__(obj, cls)
 if isinstance(ret, (Column, MapperProperty)) and \
 ret.doc is None:
 ret.doc = obj.__doc__


but still lots of failures; there’s a lot of use cases that just expect 
@declared_attr to hit once, then replace itself on the mapped class.

So the next idea is to just make a whole different command to do this, I 
sketched that up here:  www.sqlalchemy.org/trac/ticket/2952  

but I’m not really sure what I want to do with that.   mixins work great for 
single classes but within a hierarchy not so much, and adding more options 
makes me worried that we’re just adding flags rather than fixing the central 
idea somehow.  




signature.asc
Description: Message signed with OpenPGP using GPGMail


[sqlalchemy] declarative, reflection, and secondary tables.

2013-11-16 Thread Jon Nelson
I've been experiencing a weirdness.

Using SQLAlchemy 0.8.3 and PostgreSQL with declarative (and deferred
reflection), if I don't manually force a reflection *before* I call
prepare then - when I use certain objects - I get an error which
indicates that SQLAlchemy did not reflect secondary tables. Is this a
known issue? It's really hard to find an isolated test case.


InvalidRequestError: When initializing mapper
Mapper|ObjectOne|table_one, expression 'table_one_secondary_table'
failed to locate a name (name 'table_one_secondary_table' is not
defined). If this is a class name, consider adding this
relationship() to the class 'ObjectOne class after both dependent
classes have been defined.


the table 'table_one_secondary_table' is like this:

class ObjectOne(Base):
  __tablename__ = 'table_one'
  
  object_twos = relationship(
ObjectTwo, backref='object_one',
cascade=save-update,merge,refresh-expire,expunge,
secondary='table_one_secondary_table',
passive_deletes=True
  )

-- 
Jon
Software Blacksmith

-- 
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/groups/opt_out.


Re: [sqlalchemy] declarative, reflection, and secondary tables.

2013-11-16 Thread Michael Bayer

On Nov 16, 2013, at 4:08 PM, Jon Nelson jnel...@jamponi.net wrote:

 I've been experiencing a weirdness.
 
 Using SQLAlchemy 0.8.3 and PostgreSQL with declarative (and deferred
 reflection), if I don't manually force a reflection *before* I call
 prepare then - when I use certain objects - I get an error which
 indicates that SQLAlchemy did not reflect secondary tables. Is this a
 known issue? It's really hard to find an isolated test case.


that actually sounds like a real issue / missing feature since I’m not 
recalling prepare() is going to hit the “secondary” tables also.   

it should be easy to reproduce….(let’s see)….sure, simple.  this includes a 
workaround.  a new ticket with a patch is at 
http://www.sqlalchemy.org/trac/ticket/2865

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, DeferredReflection


Base = declarative_base(cls=DeferredReflection)

class A(Base):
__tablename__ = 'a'
bs = relationship(B, secondary=atob)

class B(Base):
__tablename__ = 'b'


e = create_engine(sqlite://, echo=True)
e.execute(
create table a(id integer primary key)
)
e.execute(
create table b(id integer primary key)
)
e.execute(
create table atob(
a_id integer references a(id),
b_id integer references b(id),
primary key (a_id, b_id)
)
)

Base.prepare(e)

# if this isn't done, failure
#Table('atob', Base.metadata, autoload=True, autoload_with=e)

print A.bs.__clause_element__()

 
 
 InvalidRequestError: When initializing mapper
 Mapper|ObjectOne|table_one, expression 'table_one_secondary_table'
 failed to locate a name (name 'table_one_secondary_table' is not
 defined). If this is a class name, consider adding this
 relationship() to the class 'ObjectOne class after both dependent
 classes have been defined.
 
 
 the table 'table_one_secondary_table' is like this:
 
 class ObjectOne(Base):
  __tablename__ = 'table_one'
  
  object_twos = relationship(
ObjectTwo, backref='object_one',
cascade=save-update,merge,refresh-expire,expunge,
secondary='table_one_secondary_table',
passive_deletes=True
  )
 
 -- 
 Jon
 Software Blacksmith
 
 -- 
 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/groups/opt_out.



signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Praveen
The problem with using Mixins is that you need to know the definition of
columns already for creating the mixin class. What I am trying to do is
more like get the definition dynamically on the fly.Take a look at this:

def get_properties(tablename, map):
table_inspector = reflection.Inspector.from_engine(DB_ENGINE.connect())
table = Table(tablename, metadata)
table_inspector.reflecttable(table, None)
columns = []
for child in table.get_children():
if isinstance(child, Column):
column = list(child.base_columns)[0]
column.table = None
columns.append(column)
return dict([(map[column.key],  column) for column in columns])

class CustomDeclarativeMeta(DeclarativeMeta):
def __new__(cls, name, bases, attrs):
attrs.update(get_properties(attrs.get('__tablename__'),
attrs.get('__map__')))
return super(CustomDeclarativeMeta, cls).__new__(cls, name, bases,
attrs)

# Base = declarative_base(metaclass=CustomDeclarativeMeta)
Base = declarative_base()

class Enum_SampleBase):
__tablename__ = 'Enum_Sample'
__table_args__ = {'useexisting': True}
__metaclass__ = CustomDeclarativeMeta
__map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description',
'IsActive': 'is_active'}

def __init__(self, id, name, description, is_active):
self.id = id
self.name = name
self.description = description
self.is_active = is_active

def __repr__(self):
return (%d, '%s', '%s', %r) % (self.id, self.name,
self.description, self.isactive)

Unfortunately, this isn't working. I want to declare column types by
getting them from a table that's already created in the database.



On Wed, Jul 3, 2013 at 11:11 AM, Michael Bayer mike...@zzzcomputing.comwrote:

 your metaclass must derive from the DeclarativeMeta class.

 Also, I disagree that you need this metaclass,  what you're trying to do
 is very easy using mixins, which are supported in version 0.6:
 http://docs.sqlalchemy.org/en/rel_0_6/orm/extensions/declarative.html#mixing-in-columns




 On Jul 3, 2013, at 12:44 AM, Ven Karri praveen.venk...@gmail.com wrote:

 I use: Python 2.6 and sqlalchemy 0.6.1

 This is what I am trying to do:

 from sqlalchemy.types import (
 Integer,
 String,
 Boolean
 )
 from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

 class SampleMeta(type):
 def __new__(cls, name, bases, attrs):
 attrs.update({   'id': Column('Id', Integer, primary_key=True),
 'name': Column('Name', String),
 'description': Column('Description', String),
 'is_active': Column('IsActive', Boolean)
 })
 return super(SampleMeta, cls).__new__(cls, name, bases, attrs)

 class Sample(Base):
 __tablename__ = 'Sample'
 __table_args__ = {'useexisting': True}
 __metaclass__ = SampleMeta

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 def __repr__(self):
 return (%d, '%s', '%s', %r) % (self.id, self.name,
 self.description, self.isactive)

 And the error I am getting is this:

 TypeError: Error when calling the metaclass bases
 metaclass conflict: the metaclass of a derived class must be a
 (non-strict) subclass of the metaclasses of all its bases

 Now, if I do the same thing above by using

 class Sample(object)

 instead of

 class Sample(Base)

 it works absolutely fine.

 I need to update the attributes of the class dynamically. So, I will be
 using dynamic attribute and column names. And I need the above piece code
 to work in order to be able to get there.

 **Please help**

 --
 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/groups/opt_out.




  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/37M-1Qf8HO8/unsubscribe.
 To unsubscribe from this group and all its topics, 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/groups/opt_out.






-- 
Have a nice day !!!

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To unsubscribe from 

Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Praveen
Sorry, it should've been:

class Enum_Sample(Base):

Typo.


On Mon, Aug 26, 2013 at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:

 The problem with using Mixins is that you need to know the definition of
 columns already for creating the mixin class. What I am trying to do is
 more like get the definition dynamically on the fly.Take a look at this:

 def get_properties(tablename, map):
 table_inspector = reflection.Inspector.from_engine(DB_ENGINE.connect())
 table = Table(tablename, metadata)
 table_inspector.reflecttable(table, None)
 columns = []
 for child in table.get_children():
 if isinstance(child, Column):
 column = list(child.base_columns)[0]
 column.table = None
 columns.append(column)
 return dict([(map[column.key],  column) for column in columns])

 class CustomDeclarativeMeta(DeclarativeMeta):
 def __new__(cls, name, bases, attrs):
 attrs.update(get_properties(attrs.get('__tablename__'),
 attrs.get('__map__')))
 return super(CustomDeclarativeMeta, cls).__new__(cls, name, bases,
 attrs)

 # Base = declarative_base(metaclass=CustomDeclarativeMeta)
 Base = declarative_base()

 class Enum_SampleBase):
 __tablename__ = 'Enum_Sample'
 __table_args__ = {'useexisting': True}
 __metaclass__ = CustomDeclarativeMeta
 __map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description',
 'IsActive': 'is_active'}

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 def __repr__(self):
 return (%d, '%s', '%s', %r) % (self.id, self.name,
 self.description, self.isactive)

 Unfortunately, this isn't working. I want to declare column types by
 getting them from a table that's already created in the database.



 On Wed, Jul 3, 2013 at 11:11 AM, Michael Bayer 
 mike...@zzzcomputing.comwrote:

 your metaclass must derive from the DeclarativeMeta class.

 Also, I disagree that you need this metaclass,  what you're trying to do
 is very easy using mixins, which are supported in version 0.6:
 http://docs.sqlalchemy.org/en/rel_0_6/orm/extensions/declarative.html#mixing-in-columns




 On Jul 3, 2013, at 12:44 AM, Ven Karri praveen.venk...@gmail.com wrote:

 I use: Python 2.6 and sqlalchemy 0.6.1

 This is what I am trying to do:

 from sqlalchemy.types import (
 Integer,
 String,
 Boolean
 )
  from sqlalchemy.ext.declarative import declarative_base

 Base = declarative_base()

 class SampleMeta(type):
 def __new__(cls, name, bases, attrs):
 attrs.update({   'id': Column('Id', Integer,
 primary_key=True),
 'name': Column('Name', String),
 'description': Column('Description', String),
 'is_active': Column('IsActive', Boolean)
 })
 return super(SampleMeta, cls).__new__(cls, name, bases, attrs)

 class Sample(Base):
 __tablename__ = 'Sample'
 __table_args__ = {'useexisting': True}
 __metaclass__ = SampleMeta

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 def __repr__(self):
 return (%d, '%s', '%s', %r) % (self.id, self.name,
 self.description, self.isactive)

 And the error I am getting is this:

 TypeError: Error when calling the metaclass bases
 metaclass conflict: the metaclass of a derived class must be a
 (non-strict) subclass of the metaclasses of all its bases

 Now, if I do the same thing above by using

 class Sample(object)

 instead of

 class Sample(Base)

 it works absolutely fine.

 I need to update the attributes of the class dynamically. So, I will be
 using dynamic attribute and column names. And I need the above piece code
 to work in order to be able to get there.

 **Please help**

 --
 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/groups/opt_out.




  --
 You received this message because you are subscribed to a topic in the
 Google Groups sqlalchemy group.
 To unsubscribe from this topic, visit
 https://groups.google.com/d/topic/sqlalchemy/37M-1Qf8HO8/unsubscribe.
 To unsubscribe from this group and all its topics, 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 

Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Michael Bayer

On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:

 The problem with using Mixins is that you need to know the definition of 
 columns already for creating the mixin class. What I am trying to do is more 
 like get the definition dynamically on the fly.Take a look at this:

here's a simple way to add reflection events which intercept the Column and add 
the .key of your choice, and saves on code by making use of the existing 
DeferredReflection mixin instead of hand-coding it.  There's many more variants 
on this kind of thing as well.   DeferredReflection is using some 
not-yet-public APIs to do its work, but there are other ways of deferring the 
mapping as well (typically by overriding the __mapper__ attribute).   Basically 
your class creates itself an empty Table object, to which we apply events.  
then DeferredReflection.prepare() fills in those Table objects with their 
columns using reflection.

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.ext.declarative import DeferredReflection
from sqlalchemy import event

Base = declarative_base()

e = create_engine(sqlite://, echo=True)
e.execute(
create table sample (
Id integer primary key,
Name varchar,
Description varchar,
IsActive varchar
)
)

class MagicMappyThing(DeferredReflection):
@classmethod
def __declare_last__(cls):
@event.listens_for(cls.__table__, column_reflect)
def new_col(inspector, table, column_info):
column_info['key'] = cls.__map__.get(column_info['name'], 
column_info['name'])

class Sample(MagicMappyThing, Base):
__tablename__ = 'sample'
__map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description', 
'IsActive': 'is_active'}

def __init__(self, id, name, description, is_active):
self.id = id
self.name = name
self.description = description
self.is_active = is_active

MagicMappyThing.prepare(e)

s = Session(e)

s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
s.commit()






 
 def get_properties(tablename, map):
 table_inspector = reflection.Inspector.from_engine(DB_ENGINE.connect())
 table = Table(tablename, metadata)
 table_inspector.reflecttable(table, None)
 columns = []
 for child in table.get_children():
 if isinstance(child, Column):
 column = list(child.base_columns)[0]
 column.table = None
 columns.append(column)
 return dict([(map[column.key],  column) for column in columns])
 
 class CustomDeclarativeMeta(DeclarativeMeta):
 def __new__(cls, name, bases, attrs):
 attrs.update(get_properties(attrs.get('__tablename__'), 
 attrs.get('__map__')))
 return super(CustomDeclarativeMeta, cls).__new__(cls, name, bases, 
 attrs)
 
 # Base = declarative_base(metaclass=CustomDeclarativeMeta)
 Base = declarative_base()
 
 class Enum_SampleBase):
 __tablename__ = 'Enum_Sample'
 __table_args__ = {'useexisting': True}
 __metaclass__ = CustomDeclarativeMeta
 __map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description', 
 'IsActive': 'is_active'}
 
 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active
 
 def __repr__(self):
 return (%d, '%s', '%s', %r) % (self.id, self.name, 
 self.description, self.isactive)
 
 Unfortunately, this isn't working. I want to declare column types by getting 
 them from a table that's already created in the database.
 
 
 
 On Wed, Jul 3, 2013 at 11:11 AM, Michael Bayer mike...@zzzcomputing.com 
 wrote:
 your metaclass must derive from the DeclarativeMeta class.
 
 Also, I disagree that you need this metaclass,  what you're trying to do is 
 very easy using mixins, which are supported in version 0.6: 
 http://docs.sqlalchemy.org/en/rel_0_6/orm/extensions/declarative.html#mixing-in-columns
 
 
 
 
 On Jul 3, 2013, at 12:44 AM, Ven Karri praveen.venk...@gmail.com wrote:
 
 I use: Python 2.6 and sqlalchemy 0.6.1
 
 This is what I am trying to do:
 
  from sqlalchemy.types import (
  Integer,
  String,
  Boolean
  )
  from sqlalchemy.ext.declarative import declarative_base
 
 Base = declarative_base()
 
  class SampleMeta(type):
 def __new__(cls, name, bases, attrs):
 attrs.update({   'id': Column('Id', Integer, primary_key=True),
 'name': Column('Name', String),
 'description': Column('Description', String),
 'is_active': Column('IsActive', Boolean)
 })
 return super(SampleMeta, cls).__new__(cls, name, bases, attrs)
 
 class Sample(Base):
 __tablename__ = 'Sample'
 __table_args__ = {'useexisting': True}
 __metaclass__ = 

Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Michael Bayer

On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com wrote:

 
 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:
 
 The problem with using Mixins is that you need to know the definition of 
 columns already for creating the mixin class. What I am trying to do is more 
 like get the definition dynamically on the fly.Take a look at this:
 
 here's a simple way to add reflection events which intercept the Column and 
 add the .key of your choice, and saves on code by making use of the existing 
 DeferredReflection mixin instead of hand-coding it.

except it doesnt work yet, give me 10 minutes.



signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Michael Bayer
OK here we are, had to switch approaches due to a bug with the column reflect 
event, to use the aforementioned __mapper_cls__ (had the name wrong), so I 
think you'll see this is a pretty open-ended way to control how something maps 
as you're given total access to mapper() here:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr
from sqlalchemy.ext.declarative import DeferredReflection
from sqlalchemy import event

Base = declarative_base()

e = create_engine(sqlite://, echo=True)
e.execute(
create table sample (
Id integer primary key,
Name varchar,
Description varchar,
IsActive varchar
)
)

class MagicMappyThing(DeferredReflection):
@declared_attr
def __mapper_cls__(cls):
def map_(cls, *arg, **kw):
props = kw.setdefault(properties, {})
for k, v in cls.__map__.items():
props[v] = cls.__table__.c[k]
return mapper(cls, *arg, **kw)
return map_

class Sample(MagicMappyThing, Base):
__tablename__ = 'sample'
__map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description', 
'IsActive': 'is_active'}

def __init__(self, id, name, description, is_active):
self.id = id
self.name = name
self.description = description
self.is_active = is_active

MagicMappyThing.prepare(e)

s = Session(e)

s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
s.commit()




On Aug 26, 2013, at 5:17 PM, Michael Bayer mike...@zzzcomputing.com wrote:

 
 On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 
 
 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:
 
 The problem with using Mixins is that you need to know the definition of 
 columns already for creating the mixin class. What I am trying to do is 
 more like get the definition dynamically on the fly.Take a look at this:
 
 here's a simple way to add reflection events which intercept the Column and 
 add the .key of your choice, and saves on code by making use of the existing 
 DeferredReflection mixin instead of hand-coding it.
 
 except it doesnt work yet, give me 10 minutes.
 



signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Praveen
Does this work in sqlalchemy 0.6.1 ?


On Mon, Aug 26, 2013 at 5:36 PM, Michael Bayer mike...@zzzcomputing.comwrote:

 OK here we are, had to switch approaches due to a bug with the column
 reflect event, to use the aforementioned __mapper_cls__ (had the name
 wrong), so I think you'll see this is a pretty open-ended way to control
 how something maps as you're given total access to mapper() here:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 from sqlalchemy.ext.declarative import DeferredReflection
 from sqlalchemy import event

 Base = declarative_base()

 e = create_engine(sqlite://, echo=True)
 e.execute(
 create table sample (
 Id integer primary key,
 Name varchar,
 Description varchar,
 IsActive varchar
 )
 )

 class MagicMappyThing(DeferredReflection):
 @declared_attr
 def __mapper_cls__(cls):
 def map_(cls, *arg, **kw):
 props = kw.setdefault(properties, {})
 for k, v in cls.__map__.items():
 props[v] = cls.__table__.c[k]
 return mapper(cls, *arg, **kw)
 return map_

 class Sample(MagicMappyThing, Base):
 __tablename__ = 'sample'
 __map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description',
 'IsActive': 'is_active'}

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 MagicMappyThing.prepare(e)

 s = Session(e)

 s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
 s.commit()




 On Aug 26, 2013, at 5:17 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:

 The problem with using Mixins is that you need to know the definition of
 columns already for creating the mixin class. What I am trying to do is
 more like get the definition dynamically on the fly.Take a look at this:


 here's a simple way to add reflection events which intercept the Column
 and add the .key of your choice, and saves on code by making use of the
 existing DeferredReflection mixin instead of hand-coding it.


 except it doesnt work yet, give me 10 minutes.





-- 
Have a nice day !!!

-- 
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/groups/opt_out.


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Praveen
I am getting ImportError for the following:

from sqlalchemy.ext.declarative import DeferredReflection
from sqlalchemy import event

I use sqlalchemy 0.6.1. Is there any way I can make it work in 0.6.1 ?


On Mon, Aug 26, 2013 at 5:38 PM, Praveen praveen.venk...@gmail.com wrote:

 Does this work in sqlalchemy 0.6.1 ?


 On Mon, Aug 26, 2013 at 5:36 PM, Michael Bayer 
 mike...@zzzcomputing.comwrote:

 OK here we are, had to switch approaches due to a bug with the column
 reflect event, to use the aforementioned __mapper_cls__ (had the name
 wrong), so I think you'll see this is a pretty open-ended way to control
 how something maps as you're given total access to mapper() here:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 from sqlalchemy.ext.declarative import DeferredReflection
 from sqlalchemy import event

 Base = declarative_base()

 e = create_engine(sqlite://, echo=True)
 e.execute(
 create table sample (
 Id integer primary key,
 Name varchar,
 Description varchar,
 IsActive varchar
 )
 )

 class MagicMappyThing(DeferredReflection):
 @declared_attr
 def __mapper_cls__(cls):
 def map_(cls, *arg, **kw):
 props = kw.setdefault(properties, {})
 for k, v in cls.__map__.items():
 props[v] = cls.__table__.c[k]
 return mapper(cls, *arg, **kw)
 return map_

 class Sample(MagicMappyThing, Base):
 __tablename__ = 'sample'
 __map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description',
 'IsActive': 'is_active'}

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 MagicMappyThing.prepare(e)

 s = Session(e)

 s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
 s.commit()




 On Aug 26, 2013, at 5:17 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:

 The problem with using Mixins is that you need to know the definition of
 columns already for creating the mixin class. What I am trying to do is
 more like get the definition dynamically on the fly.Take a look at this:


 here's a simple way to add reflection events which intercept the Column
 and add the .key of your choice, and saves on code by making use of the
 existing DeferredReflection mixin instead of hand-coding it.


 except it doesnt work yet, give me 10 minutes.





 --
 Have a nice day !!!




-- 
Have a nice day !!!

-- 
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/groups/opt_out.


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Michael Bayer
you'd need to hand-roll the deferred reflection part, there's an example in 0.7 
called declarative_reflection but it might require features that aren't in 
0.6.

I'd not be looking to add any kind of slick/magic systems to an 0.6 app, 0.6 is 
very early in the curve for declarative techniques.  upgrade it first, 
otherwise stick with the hacky approaches you have.



On Aug 26, 2013, at 5:38 PM, Praveen praveen.venk...@gmail.com wrote:

 Does this work in sqlalchemy 0.6.1 ?
 
 
 On Mon, Aug 26, 2013 at 5:36 PM, Michael Bayer mike...@zzzcomputing.com 
 wrote:
 OK here we are, had to switch approaches due to a bug with the column reflect 
 event, to use the aforementioned __mapper_cls__ (had the name wrong), so I 
 think you'll see this is a pretty open-ended way to control how something 
 maps as you're given total access to mapper() here:
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 from sqlalchemy.ext.declarative import DeferredReflection
 from sqlalchemy import event
 
 Base = declarative_base()
 
 e = create_engine(sqlite://, echo=True)
 e.execute(
 create table sample (
 Id integer primary key,
 Name varchar,
 Description varchar,
 IsActive varchar
 )
 )
 
 class MagicMappyThing(DeferredReflection):
 @declared_attr
 def __mapper_cls__(cls):
 def map_(cls, *arg, **kw):
 props = kw.setdefault(properties, {})
 for k, v in cls.__map__.items():
 props[v] = cls.__table__.c[k]
 return mapper(cls, *arg, **kw)
 return map_
 
 class Sample(MagicMappyThing, Base):
 __tablename__ = 'sample'
 __map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description', 
 'IsActive': 'is_active'}
 
 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active
 
 MagicMappyThing.prepare(e)
 
 s = Session(e)
 
 s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
 s.commit()
 
 
 
 
 On Aug 26, 2013, at 5:17 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 
 
 On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 
 
 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:
 
 The problem with using Mixins is that you need to know the definition of 
 columns already for creating the mixin class. What I am trying to do is 
 more like get the definition dynamically on the fly.Take a look at this:
 
 here's a simple way to add reflection events which intercept the Column and 
 add the .key of your choice, and saves on code by making use of the 
 existing DeferredReflection mixin instead of hand-coding it.
 
 except it doesnt work yet, give me 10 minutes.
 
 
 
 
 
 -- 
 Have a nice day !!!
 
 -- 
 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/groups/opt_out.



signature.asc
Description: Message signed with OpenPGP using GPGMail


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Praveen
Could you please point me to the link where I can find the example ?


On Mon, Aug 26, 2013 at 5:41 PM, Michael Bayer mike...@zzzcomputing.comwrote:

 you'd need to hand-roll the deferred reflection part, there's an example
 in 0.7 called declarative_reflection but it might require features that
 aren't in 0.6.

 I'd not be looking to add any kind of slick/magic systems to an 0.6 app,
 0.6 is very early in the curve for declarative techniques.  upgrade it
 first, otherwise stick with the hacky approaches you have.



 On Aug 26, 2013, at 5:38 PM, Praveen praveen.venk...@gmail.com wrote:

 Does this work in sqlalchemy 0.6.1 ?


 On Mon, Aug 26, 2013 at 5:36 PM, Michael Bayer 
 mike...@zzzcomputing.comwrote:

 OK here we are, had to switch approaches due to a bug with the column
 reflect event, to use the aforementioned __mapper_cls__ (had the name
 wrong), so I think you'll see this is a pretty open-ended way to control
 how something maps as you're given total access to mapper() here:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 from sqlalchemy.ext.declarative import DeferredReflection
 from sqlalchemy import event

 Base = declarative_base()

 e = create_engine(sqlite://, echo=True)
 e.execute(
 create table sample (
 Id integer primary key,
 Name varchar,
 Description varchar,
 IsActive varchar
 )
 )

 class MagicMappyThing(DeferredReflection):
 @declared_attr
 def __mapper_cls__(cls):
 def map_(cls, *arg, **kw):
 props = kw.setdefault(properties, {})
 for k, v in cls.__map__.items():
 props[v] = cls.__table__.c[k]
 return mapper(cls, *arg, **kw)
 return map_

 class Sample(MagicMappyThing, Base):
 __tablename__ = 'sample'
 __map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description',
 'IsActive': 'is_active'}

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 MagicMappyThing.prepare(e)

 s = Session(e)

 s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
 s.commit()




 On Aug 26, 2013, at 5:17 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:

 The problem with using Mixins is that you need to know the definition of
 columns already for creating the mixin class. What I am trying to do is
 more like get the definition dynamically on the fly.Take a look at this:


 here's a simple way to add reflection events which intercept the Column
 and add the .key of your choice, and saves on code by making use of the
 existing DeferredReflection mixin instead of hand-coding it.


 except it doesnt work yet, give me 10 minutes.





 --
 Have a nice day !!!

 --
 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/groups/opt_out.





-- 
Have a nice day !!!

-- 
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/groups/opt_out.


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Praveen
nvm... i found it.


On Mon, Aug 26, 2013 at 5:46 PM, Praveen praveen.venk...@gmail.com wrote:

 Could you please point me to the link where I can find the example ?


 On Mon, Aug 26, 2013 at 5:41 PM, Michael Bayer 
 mike...@zzzcomputing.comwrote:

 you'd need to hand-roll the deferred reflection part, there's an example
 in 0.7 called declarative_reflection but it might require features that
 aren't in 0.6.

 I'd not be looking to add any kind of slick/magic systems to an 0.6 app,
 0.6 is very early in the curve for declarative techniques.  upgrade it
 first, otherwise stick with the hacky approaches you have.



 On Aug 26, 2013, at 5:38 PM, Praveen praveen.venk...@gmail.com wrote:

 Does this work in sqlalchemy 0.6.1 ?


 On Mon, Aug 26, 2013 at 5:36 PM, Michael Bayer 
 mike...@zzzcomputing.comwrote:

 OK here we are, had to switch approaches due to a bug with the column
 reflect event, to use the aforementioned __mapper_cls__ (had the name
 wrong), so I think you'll see this is a pretty open-ended way to control
 how something maps as you're given total access to mapper() here:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 from sqlalchemy.ext.declarative import DeferredReflection
 from sqlalchemy import event

 Base = declarative_base()

 e = create_engine(sqlite://, echo=True)
 e.execute(
 create table sample (
 Id integer primary key,
 Name varchar,
 Description varchar,
 IsActive varchar
 )
 )

 class MagicMappyThing(DeferredReflection):
 @declared_attr
 def __mapper_cls__(cls):
 def map_(cls, *arg, **kw):
 props = kw.setdefault(properties, {})
 for k, v in cls.__map__.items():
 props[v] = cls.__table__.c[k]
 return mapper(cls, *arg, **kw)
 return map_

 class Sample(MagicMappyThing, Base):
 __tablename__ = 'sample'
 __map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description',
 'IsActive': 'is_active'}

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 MagicMappyThing.prepare(e)

 s = Session(e)

 s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
 s.commit()




 On Aug 26, 2013, at 5:17 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com wrote:

 The problem with using Mixins is that you need to know the definition of
 columns already for creating the mixin class. What I am trying to do is
 more like get the definition dynamically on the fly.Take a look at this:


 here's a simple way to add reflection events which intercept the Column
 and add the .key of your choice, and saves on code by making use of the
 existing DeferredReflection mixin instead of hand-coding it.


 except it doesnt work yet, give me 10 minutes.





 --
 Have a nice day !!!

 --
 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/groups/opt_out.





 --
 Have a nice day !!!




-- 
Have a nice day !!!

-- 
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/groups/opt_out.


Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-08-26 Thread Praveen
I tried your example in sqlalchemy 0.6 by manually plugging in api.py
library (attached) that I got from
herehttps://bitbucket.org/miracle2k/sqlalchemy/src/2d28ed97d3221a133b4b297a229deb294088affe/lib/sqlalchemy/ext/declarative/api.py?at=default
.

I get this error:

File path\to\sample_orm.py, line 33, in map_
props[v] = cls.__table__.c[k]
  File path\to\lib\python2.6\sqlalchemy\util.py, line 731, in __getitem__

KeyError: 'Description'


Here's my code:

from sqlalchemy.orm import mapper
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from .api import DeferredReflection, declared_attr -- this is coming from
attached api.py file

Base = declarative_base()

e = create_engine(sqlite://, echo=True)
e.execute(
create table Sample (
Id integer primary key,
Name varchar,
Description varchar,
IsActive varchar
)
)

class MagicMappyThing(DeferredReflection):
@declared_attr
def __mapper_cls__(cls):
def map_(cls, *arg, **kw):
props = kw.setdefault(properties, {})
for k, v in cls.__map__.items():
props[v] = cls.__table__.c[k]
return mapper(cls, *arg, **kw)
return map_

class Sample(MagicMappyThing, Base):
__tablename__ = 'Sample'
__map__ = {'Id': 'id', 'Name': 'name', 'Description': 'description',
'IsActive': 'is_active'}

def __init__(self, id, name, description, is_active):
self.id = id
self.name = name
self.description = description
self.is_active = is_active

MagicMappyThing.prepare(e)

# s = Session(e)

# s.add(Sample(id=1, name='some name', description='foo', is_active='foo'))
# s.commit()


On Mon, Aug 26, 2013 at 5:52 PM, Praveen praveen.venk...@gmail.com wrote:

 It works only in 0.7 like you said. I can't find any way to crack this
 situation in 0.6. :-(


 On Mon, Aug 26, 2013 at 5:49 PM, Praveen praveen.venk...@gmail.comwrote:

 nvm... i found it.


 On Mon, Aug 26, 2013 at 5:46 PM, Praveen praveen.venk...@gmail.comwrote:

 Could you please point me to the link where I can find the example ?


 On Mon, Aug 26, 2013 at 5:41 PM, Michael Bayer mike...@zzzcomputing.com
  wrote:

 you'd need to hand-roll the deferred reflection part, there's an
 example in 0.7 called declarative_reflection but it might require
 features that aren't in 0.6.

 I'd not be looking to add any kind of slick/magic systems to an 0.6
 app, 0.6 is very early in the curve for declarative techniques.  upgrade it
 first, otherwise stick with the hacky approaches you have.



 On Aug 26, 2013, at 5:38 PM, Praveen praveen.venk...@gmail.com wrote:

 Does this work in sqlalchemy 0.6.1 ?


 On Mon, Aug 26, 2013 at 5:36 PM, Michael Bayer 
 mike...@zzzcomputing.com wrote:

 OK here we are, had to switch approaches due to a bug with the column
 reflect event, to use the aforementioned __mapper_cls__ (had the name
 wrong), so I think you'll see this is a pretty open-ended way to control
 how something maps as you're given total access to mapper() here:

 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 from sqlalchemy.ext.declarative import DeferredReflection
 from sqlalchemy import event

 Base = declarative_base()

 e = create_engine(sqlite://, echo=True)
 e.execute(
 create table sample (
 Id integer primary key,
 Name varchar,
 Description varchar,
 IsActive varchar
 )
 )

 class MagicMappyThing(DeferredReflection):
 @declared_attr
 def __mapper_cls__(cls):
 def map_(cls, *arg, **kw):
 props = kw.setdefault(properties, {})
 for k, v in cls.__map__.items():
 props[v] = cls.__table__.c[k]
 return mapper(cls, *arg, **kw)
 return map_

 class Sample(MagicMappyThing, Base):
 __tablename__ = 'sample'
 __map__ = {'Id': 'id', 'Name': 'name', 'Description':
 'description', 'IsActive': 'is_active'}

 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active

 MagicMappyThing.prepare(e)

 s = Session(e)

 s.add(Sample(id=1, name='some name', description='foo',
 is_active='foo'))
 s.commit()




 On Aug 26, 2013, at 5:17 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 5:16 PM, Michael Bayer mike...@zzzcomputing.com
 wrote:


 On Aug 26, 2013, at 4:35 PM, Praveen praveen.venk...@gmail.com
 wrote:

 The problem with using Mixins is that you need to know the definition
 of columns already for creating the mixin class. What I am trying to do is
 more like get the definition dynamically on the fly.Take a look at this:


 here's a simple way to add reflection events which intercept the
 Column and add the .key of your choice, and saves on code by making use of
 the existing DeferredReflection mixin instead of 

Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-07-03 Thread Michael Bayer
your metaclass must derive from the DeclarativeMeta class.

Also, I disagree that you need this metaclass,  what you're trying to do is 
very easy using mixins, which are supported in version 0.6: 
http://docs.sqlalchemy.org/en/rel_0_6/orm/extensions/declarative.html#mixing-in-columns




On Jul 3, 2013, at 12:44 AM, Ven Karri praveen.venk...@gmail.com wrote:

 I use: Python 2.6 and sqlalchemy 0.6.1
 
 This is what I am trying to do:
 
   from sqlalchemy.types import (
   Integer,
   String,
   Boolean
   )
   from sqlalchemy.ext.declarative import declarative_base
 
 Base = declarative_base()
 
   class SampleMeta(type):
 def __new__(cls, name, bases, attrs):
 attrs.update({   'id': Column('Id', Integer, primary_key=True),
 'name': Column('Name', String),
 'description': Column('Description', String),
 'is_active': Column('IsActive', Boolean)
 })
 return super(SampleMeta, cls).__new__(cls, name, bases, attrs)
 
 class Sample(Base):
 __tablename__ = 'Sample'
 __table_args__ = {'useexisting': True}
 __metaclass__ = SampleMeta
 
 def __init__(self, id, name, description, is_active):
 self.id = id
 self.name = name
 self.description = description
 self.is_active = is_active
 
 def __repr__(self):
 return (%d, '%s', '%s', %r) % (self.id, self.name, 
 self.description, self.isactive)
 
 And the error I am getting is this:
 
 TypeError: Error when calling the metaclass bases
 metaclass conflict: the metaclass of a derived class must be a 
 (non-strict) subclass of the metaclasses of all its bases
 
 Now, if I do the same thing above by using
 
 class Sample(object)
 
 instead of
 
 class Sample(Base)
 
 it works absolutely fine.
 
 I need to update the attributes of the class dynamically. So, I will be using 
 dynamic attribute and column names. And I need the above piece code to work 
 in order to be able to get there.
 
 **Please help** 
 
 -- 
 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/groups/opt_out.
  
  

-- 
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/groups/opt_out.




[sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?

2013-07-02 Thread Ven Karri
I use: Python 2.6 and sqlalchemy 0.6.1

This is what I am trying to do:

from sqlalchemy.types import (
Integer,
String,
Boolean
)
from sqlalchemy.ext.declarative import declarative_base

Base = declarative_base()

class SampleMeta(type):
def __new__(cls, name, bases, attrs):
attrs.update({   'id': Column('Id', Integer, primary_key=True),
'name': Column('Name', String),
'description': Column('Description', String),
'is_active': Column('IsActive', Boolean)
})
return super(SampleMeta, cls).__new__(cls, name, bases, attrs)

class Sample(Base):
__tablename__ = 'Sample'
__table_args__ = {'useexisting': True}
__metaclass__ = SampleMeta

def __init__(self, id, name, description, is_active):
self.id = id
self.name = name
self.description = description
self.is_active = is_active

def __repr__(self):
return (%d, '%s', '%s', %r) % (self.id, self.name, 
self.description, self.isactive)

And the error I am getting is this:

TypeError: Error when calling the metaclass bases
metaclass conflict: the metaclass of a derived class must be a 
(non-strict) subclass of the metaclasses of all its bases

Now, if I do the same thing above by using

class Sample(object)

instead of

class Sample(Base)

it works absolutely fine.

I need to update the attributes of the class dynamically. So, I will be 
using dynamic attribute and column names. And I need the above piece code 
to work in order to be able to get there.

**Please help** 

-- 
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/groups/opt_out.




[sqlalchemy] Declarative Sequences

2013-06-26 Thread Mat Mathews
Apologies if I'm posting a question to this group incorrectly or with bad 
etiquette. I've been reading the emails from this group for a few years and now 
have a question myself. 

I am automating the creation of our models and business objects by reading a 
schema definition from YAML. We use the declarative base, some metaclasses and 
superclasses, a couple of mixes.. and ultimately PostgreSQL 9.x (exclusively)

I create a custom type using a metaclass that creates the primary key column 
along with anything else, and decorate anything that needs `@declared_attr` 
appropriately, for the declarative mechanism to discover it. 

Long story short,

I would like to create custom sequences using Sequence() with a start value, 
using a declared Column, and not having to construct a Table itself, as 
described in the docs here 
http://docs.sqlalchemy.org/en/latest/dialects/postgresql.html

I would like to do something like this:

class User(object):
id = Column(Integer, Sequence('user_id_seq', start=1), 
primary_key=True)

This does work, and emits the CREATE SEQUENCE, but does not set the owned table 
or the column to user.id

I get around this by using the default SERIAL, using DDL events, by updating 
the normal ALTER SEQUENCE [user_id_seq]  RESTART WITH [value]. 

However, I may have just missed something or misunderstood something deep in 
declarative.

My goal is to automate as much of the schema, model, and business object 
creation as possible using our DSL, which is leveraging the power of 
SQLAlchemy, GeoAlchemy2, PostgreSQL, and PostGIS.

Much obliged for any help,

Mat






-- 
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/groups/opt_out.




Re: [sqlalchemy] Declarative Sequences

2013-06-26 Thread Michael Bayer

On Jun 26, 2013, at 12:02 PM, Mat Mathews m...@miga.me wrote:

 I would like to do something like this:
 
 class User(object):
   id = Column(Integer, Sequence('user_id_seq', start=1), 
 primary_key=True)
 
 This does work, and emits the CREATE SEQUENCE, but does not set the owned 
 table or the column to user.id

I'm not able to reproduce, even assigning the same sequence name to two 
different tables simultaneously produces the correct result.  Can you modify 
the test below to illustrate your issue?

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr

Base = declarative_base()

class IdMixin(object):
id = Column(Integer, Sequence('user_id_seq', start=1), primary_key=True)

class A(IdMixin, Base):
__tablename__ = 'a'

class B(IdMixin, Base):
__tablename__ = 'b'

e = create_engine(postgresql://scott:tiger@localhost/test, echo=True)
Base.metadata.drop_all(e)
Base.metadata.create_all(e)

sess = Session(e)

a1 = A()
sess.add(a1)

b1 = B()
sess.add(b1)
sess.commit()

assert a1.id == 1
assert b1.id == 10001


-- 
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/groups/opt_out.




Re: [sqlalchemy] Declarative Sequences

2013-06-26 Thread Mat Mathews
Thanks for the quick reply.

If I modify the name of the sequence in the test, it reproduces what I have 
experienced. 

When I check the details on the sequence in postgres, there is no table owner 
or column specified by the sequence 'test_user_id_seq'.. and I would expect to 
see both tables `a` and `b`.

class IdMixin(object):
   id = Column(Integer, Sequence('test_user_id_seq', start=1), 
primary_key=True)

I will write a complete self contained test, that anyone can run. But wanted to 
give my immediate feedback.

Thanks so much,
Mat


On Jun 26, 2013, at 6:37 PM, Michael Bayer mike...@zzzcomputing.com wrote:

 
 On Jun 26, 2013, at 12:02 PM, Mat Mathews m...@miga.me wrote:
 
 I would like to do something like this:
 
 class User(object):
  id = Column(Integer, Sequence('user_id_seq', start=1), 
 primary_key=True)
 
 This does work, and emits the CREATE SEQUENCE, but does not set the owned 
 table or the column to user.id
 
 I'm not able to reproduce, even assigning the same sequence name to two 
 different tables simultaneously produces the correct result.  Can you modify 
 the test below to illustrate your issue?
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 
 Base = declarative_base()
 
 class IdMixin(object):
id = Column(Integer, Sequence('user_id_seq', start=1), 
 primary_key=True)
 
 class A(IdMixin, Base):
__tablename__ = 'a'
 
 class B(IdMixin, Base):
__tablename__ = 'b'
 
 e = create_engine(postgresql://scott:tiger@localhost/test, echo=True)
 Base.metadata.drop_all(e)
 Base.metadata.create_all(e)
 
 sess = Session(e)
 
 a1 = A()
 sess.add(a1)
 
 b1 = B()
 sess.add(b1)
 sess.commit()
 
 assert a1.id == 1
 assert b1.id == 10001
 
 
 -- 
 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/groups/opt_out.
 
 

-- 
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/groups/opt_out.




Re: [sqlalchemy] Declarative Sequences

2013-06-26 Thread Michael Bayer

On Jun 26, 2013, at 1:26 PM, Mat Mathews m...@miga.me wrote:

 Thanks for the quick reply.
 
 If I modify the name of the sequence in the test, it reproduces what I have 
 experienced. 
 
 When I check the details on the sequence in postgres, there is no table owner 
 or column specified by the sequence 'test_user_id_seq'.. and I would expect 
 to see both tables `a` and `b`.
 
 class IdMixin(object):
   id = Column(Integer, Sequence('test_user_id_seq', start=1), 
 primary_key=True)
 
 I will write a complete self contained test, that anyone can run. But wanted 
 to give my immediate feedback.

oh, you're looking for a linkage in PG's information schema I guess?  
Sequence() doesn't have that functionality.   My understanding was that PG's 
SERIAL created the linkage as a server default, so you can get this by adding 
this server default yourself, see below for demo:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr

Base = declarative_base()

class IdMixin(object):
id = Column(Integer,
Sequence('some_id_seq', start=1),
server_default=text(nextval('some_id_seq')),
primary_key=True)

class A(IdMixin, Base):
__tablename__ = 'a'

class B(IdMixin, Base):
__tablename__ = 'b'

e = create_engine(postgresql://scott:tiger@localhost/test, echo=True)
Base.metadata.drop_all(e)
Base.metadata.create_all(e)

sess = Session(e)

a1 = A()
sess.add(a1)

b1 = B()
sess.add(b1)
sess.commit()

assert a1.id == 1
assert b1.id == 10001

sess.execute(INSERT INTO b DEFAULT VALUES)
assert sess.execute(SELECT * FROM b WHERE id=10002).scalar()




 
 Thanks so much,
 Mat
 
 
 On Jun 26, 2013, at 6:37 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 
 
 On Jun 26, 2013, at 12:02 PM, Mat Mathews m...@miga.me wrote:
 
 I would like to do something like this:
 
 class User(object):
 id = Column(Integer, Sequence('user_id_seq', start=1), 
 primary_key=True)
 
 This does work, and emits the CREATE SEQUENCE, but does not set the owned 
 table or the column to user.id
 
 I'm not able to reproduce, even assigning the same sequence name to two 
 different tables simultaneously produces the correct result.  Can you modify 
 the test below to illustrate your issue?
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 
 Base = declarative_base()
 
 class IdMixin(object):
   id = Column(Integer, Sequence('user_id_seq', start=1), 
 primary_key=True)
 
 class A(IdMixin, Base):
   __tablename__ = 'a'
 
 class B(IdMixin, Base):
   __tablename__ = 'b'
 
 e = create_engine(postgresql://scott:tiger@localhost/test, echo=True)
 Base.metadata.drop_all(e)
 Base.metadata.create_all(e)
 
 sess = Session(e)
 
 a1 = A()
 sess.add(a1)
 
 b1 = B()
 sess.add(b1)
 sess.commit()
 
 assert a1.id == 1
 assert b1.id == 10001
 
 
 -- 
 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/groups/opt_out.
 
 
 
 -- 
 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/groups/opt_out.
 
 

-- 
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/groups/opt_out.




Re: [sqlalchemy] Declarative Sequences

2013-06-26 Thread Mat Mathews
That absolutely solves my issue. I had a serious suspicion I was missing 
something, and it was to look at the Column options, not just the Sequence. 

Thanks a ton.

On Jun 26, 2013, at 7:44 PM, Michael Bayer mike...@zzzcomputing.com wrote:

 
 On Jun 26, 2013, at 1:26 PM, Mat Mathews m...@miga.me wrote:
 
 Thanks for the quick reply.
 
 If I modify the name of the sequence in the test, it reproduces what I have 
 experienced. 
 
 When I check the details on the sequence in postgres, there is no table 
 owner or column specified by the sequence 'test_user_id_seq'.. and I would 
 expect to see both tables `a` and `b`.
 
 class IdMixin(object):
  id = Column(Integer, Sequence('test_user_id_seq', start=1), 
 primary_key=True)
 
 I will write a complete self contained test, that anyone can run. But wanted 
 to give my immediate feedback.
 
 oh, you're looking for a linkage in PG's information schema I guess?  
 Sequence() doesn't have that functionality.   My understanding was that PG's 
 SERIAL created the linkage as a server default, so you can get this by 
 adding this server default yourself, see below for demo:
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 
 Base = declarative_base()
 
 class IdMixin(object):
id = Column(Integer,
Sequence('some_id_seq', start=1),
server_default=text(nextval('some_id_seq')),
primary_key=True)
 
 class A(IdMixin, Base):
__tablename__ = 'a'
 
 class B(IdMixin, Base):
__tablename__ = 'b'
 
 e = create_engine(postgresql://scott:tiger@localhost/test, echo=True)
 Base.metadata.drop_all(e)
 Base.metadata.create_all(e)
 
 sess = Session(e)
 
 a1 = A()
 sess.add(a1)
 
 b1 = B()
 sess.add(b1)
 sess.commit()
 
 assert a1.id == 1
 assert b1.id == 10001
 
 sess.execute(INSERT INTO b DEFAULT VALUES)
 assert sess.execute(SELECT * FROM b WHERE id=10002).scalar()
 
 
 
 
 
 Thanks so much,
 Mat
 
 
 On Jun 26, 2013, at 6:37 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 
 
 On Jun 26, 2013, at 12:02 PM, Mat Mathews m...@miga.me wrote:
 
 I would like to do something like this:
 
 class User(object):
id = Column(Integer, Sequence('user_id_seq', start=1), 
 primary_key=True)
 
 This does work, and emits the CREATE SEQUENCE, but does not set the owned 
 table or the column to user.id
 
 I'm not able to reproduce, even assigning the same sequence name to two 
 different tables simultaneously produces the correct result.  Can you 
 modify the test below to illustrate your issue?
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 
 Base = declarative_base()
 
 class IdMixin(object):
  id = Column(Integer, Sequence('user_id_seq', start=1), 
 primary_key=True)
 
 class A(IdMixin, Base):
  __tablename__ = 'a'
 
 class B(IdMixin, Base):
  __tablename__ = 'b'
 
 e = create_engine(postgresql://scott:tiger@localhost/test, echo=True)
 Base.metadata.drop_all(e)
 Base.metadata.create_all(e)
 
 sess = Session(e)
 
 a1 = A()
 sess.add(a1)
 
 b1 = B()
 sess.add(b1)
 sess.commit()
 
 assert a1.id == 1
 assert b1.id == 10001
 
 
 -- 
 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/groups/opt_out.
 
 
 
 -- 
 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/groups/opt_out.
 
 
 
 -- 
 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/groups/opt_out.
 
 

-- 
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/groups/opt_out.




[sqlalchemy] Declarative and deferred

2012-08-11 Thread David McKeone
Short:
---
Is there a way to backfill multiple deferred columns in a declarative object 
result instance in a dynamic way when groups can't be predicted in the model?


Long:

First, let me just say thanks for SQLAlchemy.  This is my first post to this 
list and after working with it for quite a while I've found it to be an 
excellent tool for working with the database.  My previous work (non-Python) 
was done with a database abstraction layer that was more relational and less 
object-oriented and I've found SQLAlchemy to be amazing for letting me have my 
cake (objects) and eat it too (hand-crafted sql optimizations).

Alright, so a few caveats for background:
1) I'm fairly new to Python (~4 months), but not to programming (~10 years)
2) This is the first time I've used an ORM, so my question may be more about 
the object-relational mismatch handling, rather than SQLAlchemy directly. 
3) I'm using SQLAlchemy with Flask's plug-in flask-sqlalchemy.  That may not 
have much do with my question, but just in case there is some subtle difference 
between declarative's base model and Flask's db.Model
4) The current project is to use Flask and SQLAlchemy to create a web site with 
an existing database in a deployed client-server application (96 Tables, can be 
anywhere between ~200MB and 30GB)
5) Assumptions abound... this is a fairly complicated/specific case (I think) 
so there may be underlying assumptions about how I'm doing things that are 
incorrect.  If I'm wrong in those underlying assumptions, then feel free to 
challenge them.
6) SQLAlchemy 0.7.8

Cool.

So, I see that using declarative objects has a quite a few advantages;  you can 
easily add attributes(columns, relationships, etc...), validators, and methods 
-- all great stuff for keeping things logically grouped. Then when you get to 
performance optimizations there is a significant benefit with larger models to 
not fetch all the columns for every request (this is a web app after all, so 
lower response times are a goal).  Great, so deferred looks like the ticket to 
be able to handle this particular mis-match in a good enough way.  I can defer 
any non-essential columns and if I need one or two other columns down the line 
then they'll be lazy-loaded as required. 

Contrived example:

class User(db.Model, HelperMixin):
__tablename__ =  'user'

id = db.Column(db.Integer, primary_key=True)
password = db.Column(db.String)
type = db.Column(db.Integer)
first_name = db.Column(db.String)
last_name = db.Column(db.String)
title = db.Column(db.String)
birthday = db.Column(db.Date)
height = db.Column(db.Numeric)
width = db.Column(db.Numeric)
# etc...

   def is_valid(self, check_password):
  # check password in a horribly insecure, but easy way
  return True if check_password == self.password else False

So with this model I want to validate a users password on login, but not load 
all the other unnecessary stuff, because login probably doesn't need all the 
rest of those columns.  Because I also want to keep things simple on the model, 
I don't use deferred directly, but rather I created a couple helper methods in 
a mixin.   (Note that other parts of the application may need more columns or 
less columns or different columns, depending on context, so putting deferreds 
directly in the model would also be impractical)

The mixin looks like this:

from sqlalchemy.orm import defer
from sqlalchemy.orm.properties import ColumnProperty
from sqlalchemy.orm.util import class_mapper

class HelperMixin(object):

@classmethod
def itercolumns(cls):
for prop in class_mapper(cls).iterate_properties:
if isinstance(prop, ColumnProperty):
yield prop.key

@classmethod
def get_deferred_except(cls, *attributes):
attribute_set = set(attributes)

ret = list()
for name in cls.itercolumns():
if name not in attribute_set:
ret.append(defer(name))

return ret

so with this helper I can context sensitively build up a result object with 
just the stuff I need (but without losing the benefits of the associated 
methods):

deferred = User.get_deferred_except('id', 'password') # Get list of defer() 
instances for all columns, but those specified
user = User.query.options(*deferred).first()

# SQL Emitted -- SELECT id, password FROM user

if user.is_valid(the_password):
# Valid stuff
else:
# Invalid stuff

Ok, well that worked great, but now I need to get the patrons name for some 
runtime specific reason.  So I do this:

full_name =  .join([user.title, user.first_name, user.last_name])

I now emit:

SELECT title FROM user
SELECT first_name FROM user
SELECT last_name FROM user

When what I really want at this point, and can predictably know in this case, 
is:

SELECT title, first_name, last_name FROM user

So, the question is, what is the best way to back-fill an object in a way that 
you keep the number 

Re: [sqlalchemy] Declarative and deferred

2012-08-11 Thread Michael Bayer

On Aug 11, 2012, at 10:08 AM, David McKeone wrote:

 so with this helper I can context sensitively build up a result object with 
 just the stuff I need (but without losing the benefits of the associated 
 methods):
 
 deferred = User.get_deferred_except('id', 'password') # Get list of defer() 
 instances for all columns, but those specified
 user = User.query.options(*deferred).first()
 
 # SQL Emitted -- SELECT id, password FROM user
 
 if user.is_valid(the_password):
# Valid stuff
 else:
# Invalid stuff
 
 Ok, well that worked great, but now I need to get the patrons name for some 
 runtime specific reason.  So I do this:
 
 full_name =  .join([user.title, user.first_name, user.last_name])
 
 I now emit:
 
 SELECT title FROM user
 SELECT first_name FROM user
 SELECT last_name FROM user
 
 When what I really want at this point, and can predictably know in this case, 
 is:
 
 SELECT title, first_name, last_name FROM user
 
 So, the question is, what is the best way to back-fill an object in a way 
 that you keep the number of SQL queries low, while also getting the 
 advantages of using a declarative instance?  

think about just from a python level how that would necessarily have to work.   
the requirements are:

1. object is loaded with most attributes deferred.

2. code executes against loaded object, which asks for three attributes.the 
three attributes should load at once.   however, the request for those 
attributes are separate.

Right off, your code is going to be more verbose - user.title, user.firstname, 
user.lastname are three separate instructions. 

so no matter what, to follow the requested behavior, it *has* to be:

user = User.query.options(..).first()

load_more_attributes(user, [title, first_name, last_name])

full_name =  .join([user.title, user.first_name, user.last_name])

that is, there must be an explicit instruction of some kind that tells it to 
load these three at once.

So for load_more_attributes, two choices.  One is use the function you have:

query(User).options(User.get_deferred_except(title, first_name, 
last_name)).filter(...).first()

because, the identity map will have the effect that the same User instance is 
the target.

Or use session.refresh(), probably more direct:

session.refresh(user, [title, first_name, last_name])

also, if the columns you're actually using are along these lines, that is, they 
aren't 10K text files, I'd strongly encourage you to do some actual profiling 
to determine if all this complexity is necessary and not actually hurting 
performance much more.To pull over 3K of text over the wire in a single 
result is probably a lot less overhead than to pull 1000K of text in two or 
three queries.


 Additionally, I'd also wonder if it would be possible to make a 'faulting' 
 type of object;  one where requesting any of the deferred columns would cause 
 all of the deferred columns in that instance to be loaded.

well this is what the group feature does, if any columns in the group are 
touched, the whole group is loaded.  My advice would be to do some profiling, 
come up with groups that are tailored close enough to the groups of attributes 
that tend to be called together, and to not overthink it.


-- 
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] Declarative and deferred

2012-08-11 Thread David McKeone
 

 session.refresh(user, [title, first_name, last_name]) 


This was the part that I was missing.  It's fairly readable and it does 
exactly what I'd need.
 


 also, if the columns you're actually using are along these lines, that is, 
 they aren't 10K text files, I'd strongly encourage you to do some actual 
 profiling to determine if all this complexity is necessary and not actually 
 hurting performance much more.To pull over 3K of text over the wire in 
 a single result is probably a lot less overhead than to pull 1000K of text 
 in two or three queries. 


At this point I'm really just exploring the boundaries of the tool so that 
I can select a flexible design.  I still haven't quite found the sweet spot 
between what can/should be lazy and what cannot/shouldn't be lazy.  In the 
existing application (the non-ORM one) all of this is done with an 
abstracted form of direct SQL (kind of like SQLAlchemy core).  I'd like to 
convert some of those sections to use declarative objects instead, so the 
point of of this is to know that if I do go down that path then I could 
still optimize the columns if I needed to (read: after I profiled it and 
determined that it was necessary) without having to drop all the way down 
to SQLAlchemy core and then change things from passing objects around to 
passing keys in some circumstances.  Although it's very likely that you are 
correct and that the complexity induced from using this kind of system may 
outweigh the over-the-wire savings -- I guess we'll see when I get there.


well this is what the group feature does, if any columns in the group are 
 touched, the whole group is loaded.  My advice would be to do some 
 profiling, come up with groups that are tailored close enough to the groups 
 of attributes that tend to be called together, and to not overthink it. 


I will certainly look into this some more, since there are certainly groups 
of columns that can be naturally grouped.  Plus I imagine that 
session.refresh() would load the entire group if an attribute from a group 
was passed to it.  So that could be an interesting way to chunk it.


Thanks for responding with such a great post.  Its certainly helped me 
think through the issues from different angle.

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/zQNUzzPhzFAJ.
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] Declarative and deferred

2012-08-11 Thread Michael Bayer

On Aug 11, 2012, at 3:43 PM, David McKeone wrote:

 Plus I imagine that session.refresh() would load the entire group if an 
 attribute from a group was passed to it.  So that could be an interesting way 
 to chunk it.

I think the attributes to session.refresh() trump any deferred rules.  It will 
load just what you send it.

-- 
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] Declarative Models: Can they be used with two databases and two schema names?

2012-06-06 Thread Shawn Wheatley
Hi,

I'm trying to use my declarative models to copy data from an Oracle 
database with a non-default schema name to a SQLite database (which has no 
schema name, or at least a default name that can't be changed). Copying 
from Oracle to Oracle has not been a problem for me, but Oracle to SQLite 
will not work. The problem for me is that the schema definition used for 
SQL generation is on the table. I went through a fruitless exercise of 
calling tometadata on every table in the metadata created by the 
generated declarative base class, copying into a new MetaData object. I 
then swapped the metadata on the declarative base and ran my query, with 
the intention of swapping it back after. No luck.

The purpose of my project is to surgically extract related data for a small 
subset of accounts from our production database and bring it down to a 
local SQLite database. Does anybody have experience doing this? Am I going 
about this the wrong way?

Thanks for any help,
Shawn

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/Y6z2q5U_B8gJ.
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] Declarative Models: Can they be used with two databases and two schema names?

2012-06-06 Thread Michael Bayer
By far the easiest approach is to modify the username you're coming into Oracle 
as so that the schema in question is the default.  Or if you can, create Oracle 
synonyms (i.e. CREATE SYNONYM) in the default schema that link to the 
schema-qualified tables.

Otherwise SQLA doesn't have a lot of ability to change the schema name.  The 
tometadata() approach you've used is the best it has, however you'd need to 
declare all new classes against those Table objects.   A recipe for doing this 
is here: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/EntityName.

Another way you might do it is to put an event handler that modifies all the 
SQL to replace a particular schema name with something else, or nothing, like 
s/someschema./someotherschema./ type of thing. You can do this with the 
before_execute or before_cursor_execute events:

engine = create_engine(...)

@event.listens_for(engine, before_cursor_execute, retval=True)
def replace_schema(conn, cursor, statement, 
parameters, context, executemany):
statement = statement.sub(someschema., )
return statement, parameters




On Jun 6, 2012, at 3:51 PM, Shawn Wheatley wrote:

 Hi,
 
 I'm trying to use my declarative models to copy data from an Oracle database 
 with a non-default schema name to a SQLite database (which has no schema 
 name, or at least a default name that can't be changed). Copying from Oracle 
 to Oracle has not been a problem for me, but Oracle to SQLite will not work. 
 The problem for me is that the schema definition used for SQL generation is 
 on the table. I went through a fruitless exercise of calling tometadata on 
 every table in the metadata created by the generated declarative base class, 
 copying into a new MetaData object. I then swapped the metadata on the 
 declarative base and ran my query, with the intention of swapping it back 
 after. No luck.
 
 The purpose of my project is to surgically extract related data for a small 
 subset of accounts from our production database and bring it down to a local 
 SQLite database. Does anybody have experience doing this? Am I going about 
 this the wrong way?
 
 Thanks for any help,
 Shawn
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To view this discussion on the web visit 
 https://groups.google.com/d/msg/sqlalchemy/-/Y6z2q5U_B8gJ.
 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] Re: How do I patch SQLAlchemy declarative model dynamically with Columns of different type?

2012-05-14 Thread gostones
Does anyone have an idea what I may be doing wrong?

Thanks for your help in advance.


On May 11, 4:29 pm, gostones gosto...@gmail.com wrote:
 I am running mysql in production but would like to run a simple tests
 in a sqlite in memory db.

 The legacy mysql db has tables with columns that are mysql specific
 types, Which are declared in declarative models (subclassing
 declarative_base). I would like to run some simple tests without going
 to mysql and so would need to swap out the columns of the model.

 How do I do this? I've tried writing a patcher/unpatcher to swap out
 table in my model, but when I run some tests, I get

 OperationalError: (OperationalError) near ): syntax error u'\nCREATE
 TABLE my_table (\n)\n\n' ()

 Which makes my think that I am not patching the columns properly.

 Does anyone know how I can do this? What am I doing wrong?

 Currently, I create new columns and attach brand new Table object to
 __table__ and save the old table.

 The DB is created, create_all() is and convert_columns is run in
 setUp. drop_all() and revert_columns is run during tearDown in my
 tests

 mysql_sqlite_mapping = {INTEGER: Integer,
                         MEDIUMINT: Integer,
                         TEXT: text}

 def convert_columns(self, my_class, mapping):
     for column in my_class.__table__.columns:
         if type(column.type) in mapping:
             replacement_col = Column(column.name,
                                      mapping[type(column.type)],
                                      primary_key=column.primary_key,
                                      nullable=column.nullable,
                                      key=column.key,
                                      unique=column.unique)

             converted_columns.append(replacement_col)

     self.registry[my_class] = my_class.__table__

     my_class.__table__.metadata.remove(my_class.__table__)
     my_class.__table__ = Table(my_class.__table__.name,
                                my_class.__table__.metadata)

     for column in converted_columns:
         my_class.__table__.append_column(column)

     return my_class

 def revert_columns(self, my_class):
     saved_table = self.registry[my_class]

     metadata = my_class.__table__.metadata
     my_class.__table__.metadata.remove(my_class.__table__)

     model_class.__table__ = Table(saved_table.name,
                                   metadata)

     for column in saved_table.columns:
         column.table = None
         my_class.__table__.append_column(column)

     self.registry.pop(my_class)

-- 
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] Re: How do I patch SQLAlchemy declarative model dynamically with Columns of different type?

2012-05-14 Thread Michael Bayer

mutation of Table objects in-place is not something SQLAlchemy supports. 
I would advise using an extension method to TypeEngine called
with_variant() (search the docs for it, cut and paste is not working on
this terminal ) which allows a single type object, like a String(), to
produce multiple variants per backend, such as mysql.VARCHAR() only on the
mysql backend, plain String/VARCHAR on others.



gostones wrote:
 Does anyone have an idea what I may be doing wrong?

 Thanks for your help in advance.


 On May 11, 4:29 pm, gostones gosto...@gmail.com wrote:
 I am running mysql in production but would like to run a simple tests
 in a sqlite in memory db.

 The legacy mysql db has tables with columns that are mysql specific
 types, Which are declared in declarative models (subclassing
 declarative_base). I would like to run some simple tests without going
 to mysql and so would need to swap out the columns of the model.

 How do I do this? I've tried writing a patcher/unpatcher to swap out
 table in my model, but when I run some tests, I get

 OperationalError: (OperationalError) near ): syntax error u'\nCREATE
 TABLE my_table (\n)\n\n' ()

 Which makes my think that I am not patching the columns properly.

 Does anyone know how I can do this? What am I doing wrong?

 Currently, I create new columns and attach brand new Table object to
 __table__ and save the old table.

 The DB is created, create_all() is and convert_columns is run in
 setUp. drop_all() and revert_columns is run during tearDown in my
 tests

 mysql_sqlite_mapping = {INTEGER: Integer,
                         MEDIUMINT: Integer,
                         TEXT: text}

 def convert_columns(self, my_class, mapping):
     for column in my_class.__table__.columns:
         if type(column.type) in mapping:
             replacement_col = Column(column.name,
                                      mapping[type(column.type)],
                                      primary_key=column.primary_key,
                                      nullable=column.nullable,
                                      key=column.key,
                                      unique=column.unique)

             converted_columns.append(replacement_col)

     self.registry[my_class] = my_class.__table__

     my_class.__table__.metadata.remove(my_class.__table__)
     my_class.__table__ = Table(my_class.__table__.name,
                                my_class.__table__.metadata)

     for column in converted_columns:
         my_class.__table__.append_column(column)

     return my_class

 def revert_columns(self, my_class):
     saved_table = self.registry[my_class]

     metadata = my_class.__table__.metadata
     my_class.__table__.metadata.remove(my_class.__table__)

     model_class.__table__ = Table(saved_table.name,
                                   metadata)

     for column in saved_table.columns:
         column.table = None
         my_class.__table__.append_column(column)

     self.registry.pop(my_class)

 --
 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] How do I patch SQLAlchemy declarative model dynamically with Columns of different type?

2012-05-12 Thread gostones
I am running mysql in production but would like to run a simple tests
in a sqlite in memory db.

The legacy mysql db has tables with columns that are mysql specific
types, Which are declared in declarative models (subclassing
declarative_base). I would like to run some simple tests without going
to mysql and so would need to swap out the columns of the model.

How do I do this? I've tried writing a patcher/unpatcher to swap out
table in my model, but when I run some tests, I get

OperationalError: (OperationalError) near ): syntax error u'\nCREATE
TABLE my_table (\n)\n\n' ()

Which makes my think that I am not patching the columns properly.

Does anyone know how I can do this? What am I doing wrong?

Currently, I create new columns and attach brand new Table object to
__table__ and save the old table.

The DB is created, create_all() is and convert_columns is run in
setUp. drop_all() and revert_columns is run during tearDown in my
tests

mysql_sqlite_mapping = {INTEGER: Integer,
MEDIUMINT: Integer,
TEXT: text}

def convert_columns(self, my_class, mapping):
for column in my_class.__table__.columns:
if type(column.type) in mapping:
replacement_col = Column(column.name,
 mapping[type(column.type)],
 primary_key=column.primary_key,
 nullable=column.nullable,
 key=column.key,
 unique=column.unique)

converted_columns.append(replacement_col)

self.registry[my_class] = my_class.__table__

my_class.__table__.metadata.remove(my_class.__table__)
my_class.__table__ = Table(my_class.__table__.name,
   my_class.__table__.metadata)

for column in converted_columns:
my_class.__table__.append_column(column)

return my_class

def revert_columns(self, my_class):
saved_table = self.registry[my_class]

metadata = my_class.__table__.metadata
my_class.__table__.metadata.remove(my_class.__table__)

model_class.__table__ = Table(saved_table.name,
  metadata)

for column in saved_table.columns:
column.table = None
my_class.__table__.append_column(column)

self.registry.pop(my_class)

-- 
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] declarative versus classes mapped to multiple engines

2012-02-09 Thread Chris Withers

Hi Again,

I'm wondering if the use case I have is one that is supported...

So, the situation is that I have a bunch of classes that I need to map 
to a bunch of tables, and I'd prefer to do that declaratively. The 
spicey bit is that I need to connect to several environments a lot of 
the time and not all of these tables are available in all environments.


So, my plan is to have one engine per database I connect to.
But what to do about tables?

Am I right in thinking that I should have one MetaData object per 
engine, and that MetaData object should only have the tables in it that 
are actually present in that database?


If so, what's the recommended pattern for doing that?

Now, what about declarative? Declarative seems to like each class to 
have a MetaData object, but how do I tie that in with multiple engines 
and some tables not being present in some engines?


What about the declarative registry? I guess having only one of those is 
fine since it just maps a string name to a class object, right?


cheers,

Chris

--
Simplistix - Content Management, Batch Processing  Python Consulting
- http://www.simplistix.co.uk

--
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] declarative versus classes mapped to multiple engines

2012-02-09 Thread Michael Bayer

On Feb 9, 2012, at 1:42 PM, Chris Withers wrote:

 Hi Again,
 
 I'm wondering if the use case I have is one that is supported...
 
 So, the situation is that I have a bunch of classes that I need to map to a 
 bunch of tables, and I'd prefer to do that declaratively. The spicey bit is 
 that I need to connect to several environments a lot of the time and not all 
 of these tables are available in all environments.
 
 So, my plan is to have one engine per database I connect to.
 But what to do about tables?

So what does it mean for your application to import a module, that has a class 
MyClass, which should be mapped to a table, but when the app is running, that 
table essentially doesn't exist ?  Does that render MyClass useless and if so 
why import it ?  Otherwise, if it is still useful, and I'm guessing you're 
using the declared reflection recipe, you'd need to enhance the usage of 
prepare() such that the class is not actually mapped, since there is no table.  
 Or you do something else. This is all doable.

 
 Am I right in thinking that I should have one MetaData object per engine, and 
 that MetaData object should only have the tables in it that are actually 
 present in that database?
 
 If so, what's the recommended pattern for doing that?

Check this post, read the section Model Setup:

http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/


 
 Now, what about declarative? Declarative seems to like each class to have a 
 MetaData object, but how do I tie that in with multiple engines and some 
 tables not being present in some engines?
 
 What about the declarative registry? I guess having only one of those is fine 
 since it just maps a string name to a class object, right?

its all there, yup

-- 
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] declarative versus classes mapped to multiple engines

2012-02-09 Thread Chris Withers

On 09/02/2012 19:51, Michael Bayer wrote:



So, my plan is to have one engine per database I connect to.
But what to do about tables?


So what does it mean for your application to import a module, that has a class MyClass, 
which should be mapped to a table, but when the app is running, that table essentially doesn't 
exist ?  Does that render MyClass useless


Yes.


and if so why import it ?


Thing's like Pyramid config's scan (not the case here) and nose (one of 
the issues here) mean that it should be importable but not cause 
anything (including prepare) to blow up.



Otherwise, if it is still useful, and I'm guessing you're using the declared 
reflection recipe,


What on earth would give you that idea? ;-) (yes, yes I am...)


you'd need to enhance the usage of prepare() such that the class is not 
actually mapped, since there is no table.


Yeah, I had this working with the Table call wrapped in a try/except.


Check this post, read the section Model Setup:

http://techspot.zzzeek.org/2012/01/11/django-style-database-routers-in-sqlalchemy/


Almost, but...

We can't have per-connection models, that would be semantically weird.
Using a different metadata at session creation time, keyed off the dsn 
of the database connected to, and with irrelevant classes blowing up if 
used but ignored otherwise is semantically what I'm after. Clues as to 
how to implement gratefully received...


Chris

--
Simplistix - Content Management, Batch Processing  Python Consulting
   - http://www.simplistix.co.uk

--
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] declarative versus classes mapped to multiple engines

2012-02-09 Thread Michael Bayer

On Feb 9, 2012, at 3:02 PM, Chris Withers wrote:

 Almost, but...
 
 We can't have per-connection models, that would be semantically weird.
 Using a different metadata at session creation time, keyed off the dsn of the 
 database connected to, and with irrelevant classes blowing up if used but 
 ignored otherwise is semantically what I'm after. Clues as to how to 
 implement gratefully received...

do you have multiple, simultaneous engines when the app runs, where some 
engines might not be available,  or just one engine, pointing to a database 
that has some subset of required tables ?   this is confusing me.

what's not working with the try/except on the reflection ?


-- 
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] declarative versus classes mapped to multiple engines

2012-02-09 Thread Chris Withers

On 09/02/2012 20:06, Michael Bayer wrote:


On Feb 9, 2012, at 3:02 PM, Chris Withers wrote:


Almost, but...

We can't have per-connection models, that would be semantically weird.
Using a different metadata at session creation time, keyed off the dsn of the 
database connected to, and with irrelevant classes blowing up if used but 
ignored otherwise is semantically what I'm after. Clues as to how to implement 
gratefully received...


do you have multiple, simultaneous engines when the app runs,


Yes. Some will have totally different schemas, where I wouldn't imagine 
any mapped classes would interact with each other. For these, I'd 
imagine a separate MetaData instance as in the Model Setup section 
would work.


However, some will have very similar schemas^1 with just a few tables 
deliberately missing. Here, it's okay (ie: programmer error) if 
queries involving classes mapped to these blow up because the wrong 
engine is used and so a table is missing. But, the reflection needs to 
not blow up.


With one metadata object shared between these engines (which is what 
declarative with reflection appears to support), if the first engine 
used in an app (and these can be web apps and, just as annoyingly, unit 
test runs, where the order is arbitrary) is one where a table is 
missing, the class will be declaratively mapped, but the reflection will 
fail, so it won't ever get mapped and will blow up if later used with an 
engine that *does* have the table.


So, in my head I'm thinking of something like (excuse the hand waving):

data_per_dsn = dict()

def getSession(dsn):
if dsn not in data_per_dsn:
engine = make_engine(dsn) # ^2
metadata = MetaData()
reflect_tables_and_map_declarative_classes(metadata, engine)
data_per_dsn[dsn] = engine, metadata
engine, metadata = data_per_dsn[dsn]
return make_session(engine, metadata?)

...which would solve both the cases above.

The main problem I see is the case where the above would result in two 
metadata objects for one declarative class.


Wow, I feel like I'm making a hash of describing this, I'm hope I'm 
vaguely succeeding in getting the info across :-S


Chris

^1 Let's pretend that it's just missing tables, the fact that supposedly 
identical tables in different environments have evolved over time to 
have different primary keys^3 and numbers of columns is *not* something 
SQLAlchemy should have to deal with ;-)


^2 Oh for a function in SQLAlchemy to turn a dsn into a SQLAlchemy URL, 
and maybe back again...


^3 Let's also pretend that (seriously?!) some tables had not ended up 
with unique indexes that postgres is happy enough with but SQLAlchemy 
doesn't reflect correctly, because they're not *actually* primary keys - 
*sigh* - again, SA should not have to deal with this ;-)


--
Simplistix - Content Management, Batch Processing  Python Consulting
   - http://www.simplistix.co.uk

--
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] declarative and late reflection?

2011-12-27 Thread peter sabaini
Cool -- works nicely, thanks again!

On Fri, Dec 23, 2011 at 2:56 AM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Dec 22, 2011, at 7:28 PM, Michael Bayer wrote:

  this could work really nicely with extend_existing, which has been
 enhanced in 0.7.4, but there seem to be some glitches preventing it from
 being super nice, so I can't get that to work right now.  Just send in
 those columns via your own means:

 Those glitches have a pending patch in ticket 2356:
 http://www.sqlalchemy.org/trac/ticket/2356  See the modified example case
 there.  In 0.7.5 your use case will work exactly as you intend, where
 you'll be able to add Column objects to your declared class that will take
 precedence over what's autoloaded.


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




-- 
http://sabaini.at

-- 
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] declarative and late reflection?

2011-12-22 Thread peter sabaini
Hey list,

this sounds like it should be a FAQ, didn't find anything though:

I want to use the ORM in a declarative style and have the table
definition reflected, eg sth like:

class A(declarative_base()):
__tablename__ = 'A'
__table_args__ = {'autoload' : True}

However to do this SA (quite reasonably, really) already needs an
engine. For various reasons I can only construct one after import time
however. Is there a way to do a kind of late reflection, ie. have
the above class definition but trigger the reflection part later? I
could of course generate the class object later in a function when the
engine is already available but maybe there's something more
elegant...

Many thanks,
peter.

-- 
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] declarative and late reflection?

2011-12-22 Thread Michael Bayer

On Dec 22, 2011, at 9:37 AM, peter sabaini wrote:

 Hey list,
 
 this sounds like it should be a FAQ, didn't find anything though:
 
 I want to use the ORM in a declarative style and have the table
 definition reflected, eg sth like:
 
 class A(declarative_base()):
__tablename__ = 'A'
__table_args__ = {'autoload' : True}
 
 However to do this SA (quite reasonably, really) already needs an
 engine. For various reasons I can only construct one after import time
 however. Is there a way to do a kind of late reflection, ie. have
 the above class definition but trigger the reflection part later? I
 could of course generate the class object later in a function when the
 engine is already available but maybe there's something more
 elegant...

I was about to type up this recipe on the wiki and then most awesomely I 
already did it for someone !   hooray.  The current technique for this is at 
http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DeclarativeReflectedBase .


-- 
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] declarative and late reflection?

2011-12-22 Thread peter sabaini
Hey!

This works for me -- almost :-)

In my use case I need to override a column (to provide an artificial FK --
some *erm old school mysql db) which seems to trigger SA into trying to
reflect early

Observe:

from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base, declared_attr

class DeclarativeReflectedBase(object):
_mapper_args = []

@classmethod
def __mapper_cls__(cls, *args, **kw):
Declarative will use this function in lieu of
calling mapper() directly.

Collect each series of arguments and invoke
them when prepare() is called.


cls._mapper_args.append((args, kw))

@classmethod
def prepare(cls, engine):
Reflect all the tables and map !
for args, kw in cls._mapper_args:
klass = args[0]
klass.__table__ = table = Table(
klass.__tablename__,
cls.metadata,
autoload=True,
autoload_with=engine)
klass.__mapper__ = mapper(klass, table, **kw)

@declared_attr
def __table__(cls):
Return a placeholder to lull declarative into complacency
return object()

Base = declarative_base(cls=DeclarativeReflectedBase)

class Foo(Base):
__tablename__ = 'foo'
quux = Column(String)
bars = relationship(Bar)

class Bar(Base):
__tablename__ = 'bar'


Gives:

Traceback (most recent call last):
  File stdin, line 1, in module
  File /usr/tmp/Python6244Mux.py, line 40, in module
class Foo(Base):
  File
/usr/lib/python2.6/site-packages/SQLAlchemy-0.7.4-py2.6-linux-x86_64.egg/sqlalchemy/ext/declarative.py,
line 1273, in __init__
_as_declarative(cls, classname, cls.__dict__)
  File
/usr/lib/python2.6/site-packages/SQLAlchemy-0.7.4-py2.6-linux-x86_64.egg/sqlalchemy/ext/declarative.py,
line 1177, in _as_declarative
if not table.c.contains_column(c):
AttributeError: 'object' object has no attribute 'c'

Hm, maybe I can try to add the column override later?

Thanks again

peter.

On Thu, Dec 22, 2011 at 4:41 PM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Dec 22, 2011, at 9:37 AM, peter sabaini wrote:

  Hey list,
 
  this sounds like it should be a FAQ, didn't find anything though:
 
  I want to use the ORM in a declarative style and have the table
  definition reflected, eg sth like:
 
  class A(declarative_base()):
 __tablename__ = 'A'
 __table_args__ = {'autoload' : True}
 
  However to do this SA (quite reasonably, really) already needs an
  engine. For various reasons I can only construct one after import time
  however. Is there a way to do a kind of late reflection, ie. have
  the above class definition but trigger the reflection part later? I
  could of course generate the class object later in a function when the
  engine is already available but maybe there's something more
  elegant...

 I was about to type up this recipe on the wiki and then most awesomely I
 already did it for someone !   hooray.  The current technique for this is
 at
 http://www.sqlalchemy.org/trac/wiki/UsageRecipes/DeclarativeReflectedBase.


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




-- 
http://sabaini.at

-- 
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] declarative and late reflection?

2011-12-22 Thread Michael Bayer

On Dec 22, 2011, at 11:48 AM, peter sabaini wrote:

 Hey!
 
 This works for me -- almost :-)
 
 In my use case I need to override a column (to provide an artificial FK -- 
 some *erm old school mysql db) which seems to trigger SA into trying to 
 reflect early
 
 Observe:
 
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative import declarative_base, declared_attr
 
 class DeclarativeReflectedBase(object):
 _mapper_args = []
 
 @classmethod
 def __mapper_cls__(cls, *args, **kw):
 Declarative will use this function in lieu of 
 calling mapper() directly.
 
 Collect each series of arguments and invoke
 them when prepare() is called.
 
 
 cls._mapper_args.append((args, kw))
 
 @classmethod
 def prepare(cls, engine):
 Reflect all the tables and map !
 for args, kw in cls._mapper_args:
 klass = args[0]
 klass.__table__ = table = Table(
 klass.__tablename__, 
 cls.metadata, 
 autoload=True, 
 autoload_with=engine)
 klass.__mapper__ = mapper(klass, table, **kw)
 
 @declared_attr
 def __table__(cls):
 Return a placeholder to lull declarative into complacency
 return object()
 
 Base = declarative_base(cls=DeclarativeReflectedBase)
 
 class Foo(Base):
 __tablename__ = 'foo'
 quux = Column(String)
 bars = relationship(Bar)
 
 class Bar(Base):
 __tablename__ = 'bar'
 
 

yah well you want to not declare Column objects on the declared class directly 
in this case because that trips off declarative into building up a Table, which 
you don't have here, it only returns object.

this could work really nicely with extend_existing, which has been enhanced in 
0.7.4, but there seem to be some glitches preventing it from being super nice, 
so I can't get that to work right now.  Just send in those columns via your own 
means:

class Base(object):
# ...

extra_cols = []

@classmethod
def prepare(cls, engine):
Reflect all the tables and map !
for args, kw in cls._mapper_args:
klass = args[0]
klass.__table__ = table = Table(
klass.__tablename__, 
cls.metadata, 
autoload=True, 
autoload_with=engine,
*klass.extra_cols
)
klass.__mapper__ = mapper(klass, table, **kw)


class Bar(Base):
__tablename__ = 'bar'

extra_cols = [
Column('foo_id', Integer, ForeignKey('foo.id')),
]

-- 
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] declarative and late reflection?

2011-12-22 Thread Michael Bayer

On Dec 22, 2011, at 7:28 PM, Michael Bayer wrote:

 this could work really nicely with extend_existing, which has been enhanced 
 in 0.7.4, but there seem to be some glitches preventing it from being super 
 nice, so I can't get that to work right now.  Just send in those columns via 
 your own means:

Those glitches have a pending patch in ticket 2356: 
http://www.sqlalchemy.org/trac/ticket/2356  See the modified example case 
there.  In 0.7.5 your use case will work exactly as you intend, where you'll be 
able to add Column objects to your declared class that will take precedence 
over what's autoloaded.


-- 
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] Declarative Mapping vs Classic Mapping

2011-10-17 Thread Manav Goel
My question is regarding sqlalchemy version 0.7.2.

Are there any limitations in using declarative or classic mapping
while using sqlalchemy?

My main concern is there any limitation of declarative mapping which
can put me in some situation where I am stuck with the tables it will
create?

Also what about table schema changes, If I want to add a column or
remove a column from table I simply add or remove that attribute in
declarative class?

I have completed my table design and thinking to create database in
one go using declarative mapping.

-- 
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] Declarative Mapping vs Classic Mapping

2011-10-17 Thread Michael Bayer

On Oct 17, 2011, at 1:05 PM, Manav Goel wrote:

 My question is regarding sqlalchemy version 0.7.2.
 
 Are there any limitations in using declarative or classic mapping
 while using sqlalchemy?

there's not, a declarative mapping is nothing more than a small organizing 
layer on top of the classical system of class + Table + mapper() - all three 
elements are used in the same way.

 
 My main concern is there any limitation of declarative mapping which
 can put me in some situation where I am stuck with the tables it will
 create?

Declarative allows the full range of table specification that plain Table() 
allows, and additionally you can use the Table construct directly with any 
declarative class (I use this style in my current project) as demonstrated at 
http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#using-a-hybrid-approach-with-table
 .


 
 Also what about table schema changes, If I want to add a column or
 remove a column from table I simply add or remove that attribute in
 declarative class?

That's a different story.   SQLAlchemy's table metadata is only an in-python 
document describing the structure of an existing schema in a remote database.   
While table metadata has the ability to emit CREATE statements to this remote 
database, that's as far as it goes.   When using relational databases, adding 
columns means that an ALTER statement must be emitted on the target database.   
You'd need to emit these ALTER commands yourself, if you'd like an existing 
schema to gain new columns that you've added to your SQLalchemy model.  Or if 
you're in development, you can alternatively (and IMHO this is much easier, 
assuming you're working only with development databases) drop the whole 
database and recreate it, where the new columns will be present.

There is also the approach of using a tool like SQLAlchemy-Migrate which gives 
you a place to define table alterations, and does the work of composing the 
ALTER statements in a semi-automated fashion.

Regardless, the choice of declarative versus classical has no impact here, save 
for the fact that SQLAlchemy-Migrate works a little more clearly when you give 
it Table constructs to work with, rather than copies of your declared classes.  
 When I've used migrate in the past, it's entirely unnecessary to copy the full 
table definition as its docs suggest, I tend to just use Table(mytable, 
metadata, autoload=True) to get at the current Table object before applying 
alterations, so the usage of declarative has no impact.

 
 I have completed my table design and thinking to create database in
 one go using declarative mapping.

should be fine it's not that much of a commitment !

-- 
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] Declarative Mapping vs Classic Mapping

2011-10-17 Thread Manav Goel
Thanks for the quick reply.

One question here, suppose I add column using Alter Table command and then in 
class declaration the attribute. Will it see the newly added column then or not?

Concern is not issuing ALTER command by hand but is the class can see the newly 
added column.

Regards,
Manav Goel
On 17-Oct-2011, at 11:06 PM, Michael Bayer wrote:

 
 On Oct 17, 2011, at 1:05 PM, Manav Goel wrote:
 
 My question is regarding sqlalchemy version 0.7.2.
 
 Are there any limitations in using declarative or classic mapping
 while using sqlalchemy?
 
 there's not, a declarative mapping is nothing more than a small organizing 
 layer on top of the classical system of class + Table + mapper() - all three 
 elements are used in the same way.
 
 
 My main concern is there any limitation of declarative mapping which
 can put me in some situation where I am stuck with the tables it will
 create?
 
 Declarative allows the full range of table specification that plain Table() 
 allows, and additionally you can use the Table construct directly with any 
 declarative class (I use this style in my current project) as demonstrated at 
 http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#using-a-hybrid-approach-with-table
  .
 
 
 
 Also what about table schema changes, If I want to add a column or
 remove a column from table I simply add or remove that attribute in
 declarative class?
 
 That's a different story.   SQLAlchemy's table metadata is only an in-python 
 document describing the structure of an existing schema in a remote database. 
   While table metadata has the ability to emit CREATE statements to this 
 remote database, that's as far as it goes.   When using relational databases, 
 adding columns means that an ALTER statement must be emitted on the target 
 database.   You'd need to emit these ALTER commands yourself, if you'd like 
 an existing schema to gain new columns that you've added to your SQLalchemy 
 model.  Or if you're in development, you can alternatively (and IMHO this is 
 much easier, assuming you're working only with development databases) drop 
 the whole database and recreate it, where the new columns will be present.
 
 There is also the approach of using a tool like SQLAlchemy-Migrate which 
 gives you a place to define table alterations, and does the work of composing 
 the ALTER statements in a semi-automated fashion.
 
 Regardless, the choice of declarative versus classical has no impact here, 
 save for the fact that SQLAlchemy-Migrate works a little more clearly when 
 you give it Table constructs to work with, rather than copies of your 
 declared classes.   When I've used migrate in the past, it's entirely 
 unnecessary to copy the full table definition as its docs suggest, I tend to 
 just use Table(mytable, metadata, autoload=True) to get at the current 
 Table object before applying alterations, so the usage of declarative has no 
 impact.
 
 
 I have completed my table design and thinking to create database in
 one go using declarative mapping.
 
 should be fine it's not that much of a commitment !
 
 -- 
 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.



Re: [sqlalchemy] Declarative Mapping vs Classic Mapping

2011-10-17 Thread Michael Bayer
The usual development model encouraged by SQLAlchemy is that class and table 
definitions are a fixed element of your program, declared at the module level.  
  So typically, adding new columns means you're modifying the source code of 
your app, then rerunning.

That said, if you add a column to a declarative model at runtime, the 
Declarative metaclass does intercept this and will invoke add_column() on the 
Table as well as add_property() on the mapper.Existing objects created 
against the mapper will have undefined behavior regarding this new attribute, 
however, which again speaks to the practice that an app should really be run 
with against a fixed schema - the additive modification supported by Table 
and mapper() still assumes the application is setting itself up when these 
methods are called, and that the program hasn't already been running for some 
time.



On Oct 17, 2011, at 1:47 PM, Manav Goel wrote:

 Thanks for the quick reply.
 
 One question here, suppose I add column using Alter Table command and then in 
 class declaration the attribute. Will it see the newly added column then or 
 not?
 
 Concern is not issuing ALTER command by hand but is the class can see the 
 newly added column.
 
 Regards,
 Manav Goel
 On 17-Oct-2011, at 11:06 PM, Michael Bayer wrote:
 
 
 On Oct 17, 2011, at 1:05 PM, Manav Goel wrote:
 
 My question is regarding sqlalchemy version 0.7.2.
 
 Are there any limitations in using declarative or classic mapping
 while using sqlalchemy?
 
 there's not, a declarative mapping is nothing more than a small organizing 
 layer on top of the classical system of class + Table + mapper() - all three 
 elements are used in the same way.
 
 
 My main concern is there any limitation of declarative mapping which
 can put me in some situation where I am stuck with the tables it will
 create?
 
 Declarative allows the full range of table specification that plain Table() 
 allows, and additionally you can use the Table construct directly with any 
 declarative class (I use this style in my current project) as demonstrated 
 at 
 http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#using-a-hybrid-approach-with-table
  .
 
 
 
 Also what about table schema changes, If I want to add a column or
 remove a column from table I simply add or remove that attribute in
 declarative class?
 
 That's a different story.   SQLAlchemy's table metadata is only an in-python 
 document describing the structure of an existing schema in a remote 
 database.   While table metadata has the ability to emit CREATE statements 
 to this remote database, that's as far as it goes.   When using relational 
 databases, adding columns means that an ALTER statement must be emitted on 
 the target database.   You'd need to emit these ALTER commands yourself, if 
 you'd like an existing schema to gain new columns that you've added to your 
 SQLalchemy model.  Or if you're in development, you can alternatively (and 
 IMHO this is much easier, assuming you're working only with development 
 databases) drop the whole database and recreate it, where the new columns 
 will be present.
 
 There is also the approach of using a tool like SQLAlchemy-Migrate which 
 gives you a place to define table alterations, and does the work of 
 composing the ALTER statements in a semi-automated fashion.
 
 Regardless, the choice of declarative versus classical has no impact here, 
 save for the fact that SQLAlchemy-Migrate works a little more clearly when 
 you give it Table constructs to work with, rather than copies of your 
 declared classes.   When I've used migrate in the past, it's entirely 
 unnecessary to copy the full table definition as its docs suggest, I tend to 
 just use Table(mytable, metadata, autoload=True) to get at the current 
 Table object before applying alterations, so the usage of declarative has no 
 impact.
 
 
 I have completed my table design and thinking to create database in
 one go using declarative mapping.
 
 should be fine it's not that much of a commitment !
 
 -- 
 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.
 

-- 
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] declarative __table__ columns

2011-08-12 Thread Mark Erbaugh
Is there a way to access the parameters to the Column() call used to set up a 
database table when given either an instance field or class field?

For example:

class MyClass(Base):
...
f1 = Column(Integer, nullable=False, info={'min':0})
...

If I have MyClass.f1 or my_class.f1 (where my_class is an instance of MyClass) 
is there a way to get nullable or info?

The only way I've come up with so far is to match the __table__.columns 
elements on the name parameter.

Thanks,
Mark

-- 
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] declarative __table__ columns

2011-08-12 Thread Michael Bayer

On Aug 12, 2011, at 5:05 PM, Mark Erbaugh wrote:

 Is there a way to access the parameters to the Column() call used to set up a 
 database table when given either an instance field or class field?
 
 For example:
 
 class MyClass(Base):
   ...
   f1 = Column(Integer, nullable=False, info={'min':0})
   ...
 
 If I have MyClass.f1 or my_class.f1 (where my_class is an instance of 
 MyClass) is there a way to get nullable or info?
 
 The only way I've come up with so far is to match the __table__.columns 
 elements on the name parameter.

if you have MyClass.fi, column is MyClass.f1.property.columns[0].


-- 
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] declarative __table__ columns

2011-08-12 Thread Mark Erbaugh

On Aug 12, 2011, at 5:26 PM, Michael Bayer wrote:

 
 Is there a way to access the parameters to the Column() call used to set up 
 a database table when given either an instance field or class field?
 
 For example:
 
 class MyClass(Base):
  ...
  f1 = Column(Integer, nullable=False, info={'min':0})
  ...
 
 If I have MyClass.f1 or my_class.f1 (where my_class is an instance of 
 MyClass) is there a way to get nullable or info?
 
 The only way I've come up with so far is to match the __table__.columns 
 elements on the name parameter.
 
 if you have MyClass.fi, column is MyClass.f1.property.columns[0].


Thanks - just what I was looking for!

Mark

-- 
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] Declarative Field Type 'Alias'

2011-08-06 Thread Wichert Akkerman

On 08/05/2011 10:46 PM, Mark Erbaugh wrote:

This is more of a Python issue than a SA issue, but I had trouble getting this to 
work. I did, but the code seems a little awkard to mesigh.  In addition to 
the requirements already, I also wanted toe default value to be a class level 
'constant'.  The problem, as I see it, is that since the class definition isn't 
complete, it's namespace isn't avaialble.  Since the default value 'constant' is a 
class data member, it would make sense if the function were a @classmethod, but I 
couldn't get python to accept:

class  Table(Base):

...

DEFAULT = 2

@classmethod
def CustomColumn(cls):
return Column(Integer, default=DEFAULT)


that should be cls.DEFAULT


...

field1 = CustomColumn()

Python complained 'classmethod object is not callable' on the last line above.


You can only call a class method on a class. In this case that would be 
Table.CustomColumn(). However since the Table class is not available at 
this point you can't do that. You can do this sort of thing with 
metaclasses, but I would not recommend going down that paht.




What I finally ended up with that works is:

class Table(Base):
...
DEFAULT = 2

def CustomColumn(default=DEFAULT):
return Column(Integer, default=default)

...

field1 = CustomColumn()


That looks like a pretty good solution.

Wichert.

--
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] Declarative Field Type 'Alias'

2011-08-05 Thread Mark Erbaugh
In my application, some tables have several fields that need to have the same 
type and default value, i.e.:

field1 = Column(Integer, default=2)
field2 = Column(Integer, default=2)
...

Is there some way to refactor the Common(Integer, default=2), short of creating 
a custom column type?  I could see the possibility that in a future version of 
the application, I would want to globally change the column type or default 
value for all these fields at once.

So far, I've come up with creating a function that returns the column.

def common_field():
return Column(Integer, default=2)

field1 = common_field()
field2 = common_field()

Is there a better way?

Mark

-- 
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] Declarative Field Type 'Alias'

2011-08-05 Thread Michael Bayer

On Aug 5, 2011, at 1:36 PM, Mark Erbaugh wrote:

 In my application, some tables have several fields that need to have the same 
 type and default value, i.e.:
 
 field1 = Column(Integer, default=2)
 field2 = Column(Integer, default=2)
 ...
 
 Is there some way to refactor the Common(Integer, default=2), short of 
 creating a custom column type?  I could see the possibility that in a future 
 version of the application, I would want to globally change the column type 
 or default value for all these fields at once.
 
 So far, I've come up with creating a function that returns the column.
 
 def common_field():
   return Column(Integer, default=2)
 
 field1 = common_field()
 field2 = common_field()
 
 Is there a better way?

What's the issue with using a function to generate a Column of a certain 
pre-determined configuration (what are functions in a procedural language for 
if not this) ?  

FTR I use functions to generate prefab Column objects all the time and they are 
also intrinsic to the example application I've created for the SQLAlchemy book 
project (which is on a somewhat indefinite schedule at the moment, unless 
someone wants to help write) .

If the issue is that these tables need to have a certain series of completely 
fixed columns, i.e. same names and everything, here are a series of approaches 
for that depending on what you're doing.

1. Regular declarative ?  Use declarative mixins. 

class MyMixin(object):
 updated_at = Column(DateTime, onupdate=datetime.utcnow)

2. if I am using Table metadata directly (i.e. with declarative, __table__ = 
Table()), I'd typically use a function around Table:

def standard_table(*args, **kw):
return Table(*(args + [_standard_table_cols()]), **kw)

3. For all tables, use events:

@event.listens_for(Table, after_parent_attach)
def _table_standard_cols(table, metadata):
table.append_column(Column(DateTime, onupdate=datetime.utcnow))

4. Certain classes of tables...there's probably a nice way to combine the table 
events with a subset of table classes.   (tries...success !)

from sqlalchemy import *
from sqlalchemy import event
from sqlalchemy.schema import CreateTable
import datetime

class TableWithUTC(Table):
pass

@event.listens_for(TableWithUTC, after_parent_attach)
def _add_col(table, metadata):
table.append_column(Column('updated_at', DateTime, 
onupdate=datetime.datetime.utcnow))

m = MetaData()

t1 = Table('t1', m, Column('x', Integer))
t2 = TableWithUTC('t2', m, Column('x', Integer))
t3 = TableWithUTC('t3', m, Column('x', Integer))
t4 = Table('t4', m, Column('x', Integer))

assert t2.c.updated_at is not None
assert 'updated_at' not in t4.c

for name in 't1', 't2', 't3', 't4':
print CreateTable(m.tables[name])






-- 
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] Declarative Field Type 'Alias'

2011-08-05 Thread Mark Erbaugh

On Aug 5, 2011, at 3:51 PM, Michael Bayer wrote:

 On Aug 5, 2011, at 1:36 PM, Mark Erbaugh wrote:
 
 In my application, some tables have several fields that need to have the 
 same type and default value, i.e.:
 
 field1 = Column(Integer, default=2)
 field2 = Column(Integer, default=2)
 ...
 
 Is there some way to refactor the Common(Integer, default=2), short of 
 creating a custom column type?  I could see the possibility that in a future 
 version of the application, I would want to globally change the column type 
 or default value for all these fields at once.
 
 So far, I've come up with creating a function that returns the column.
 
 def common_field():
  return Column(Integer, default=2)
 
 field1 = common_field()
 field2 = common_field()
 
 Is there a better way?
 
 What's the issue with using a function to generate a Column of a certain 
 pre-determined configuration (what are functions in a procedural language for 
 if not this) ?  


No issue at all.  I just wanted to make sure I was doing it 'the right way'.  I 
just noticed that in several places, SA will let you pass in a class or an 
instance of a class and figures out what to do with it.  I thought that 
something like that might be working here.

Actually, there is a small issue with using a function: Where should the 
function live?  Obviously for some schema, this field type is used in multiple 
tables and belongs in a global namespace, but for others (as in my 
application), the field type is unique to an individual table. It would be nice 
if the function could live in the class's namespace.

This is more of a Python issue than a SA issue, but I had trouble getting this 
to work. I did, but the code seems a little awkard to me sigh.  In addition 
to the requirements already, I also wanted toe default value to be a class 
level 'constant'.  The problem, as I see it, is that since the class definition 
isn't complete, it's namespace isn't avaialble.  Since the default value 
'constant' is a class data member, it would make sense if the function were a 
@classmethod, but I couldn't get python to accept:

class  Table(Base):

...

DEFAULT = 2

@classmethod
def CustomColumn(cls):
return Column(Integer, default=DEFAULT)

...

field1 = CustomColumn()

Python complained 'classmethod object is not callable' on the last line above.

Next I tried changing that line to:

field1 = Table.CustomColumn()

Now Python complained 'Table' is not  defined

If I leave the @classmethod decroator off, I couldn't figure out how to 
reference the class level data DEFAULT.

Python complained on the return Column(... line ' global name DEFAULT is not 
defined.

What I finally ended up with that works is:

class Table(Base):
...
DEFAULT = 2

def CustomColumn(default=DEFAULT):
return Column(Integer, default=default)

...

field1 = CustomColumn()

Mark


-- 
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] Declarative: Joined Inheritance + Two Tables To One Object

2011-05-23 Thread Israel Ben Guilherme Fonseca
I have the following:

class Person(Base):
   __tablename__ = 'pessoa'
   id = Column(id_person), Integer, primary_key = True)
   name = Column(String)

class Teacher(Person):
   __tablename__ = 'teacher'
   id = Column(id_teacher, Integer, ForeignKey(Person.id),
primary_key=True)
   info = Column(String)

class Salary(Base):
   __tablename__ = 'salary'
  id = Column(String)
  value = Column(Numeric)

That's ok, but I wanted to merge the Salary and Teacher objects following
the guide:

http://www.sqlalchemy.org/docs/06/orm/mapper_config.html#mapping-a-class-against-multiple-tables

Am I forced to map the Teacher and Salary in the non-declarative mode to
achieve this? It's nice to keep things declarative, because it automatically
create the __init__ method with the columns as parameters.

I have another classes that have relationships to those classes (and they
are declarative too), and things get nasty when I mix declarative with the
standard way.

-- 
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] Declarative Class registry ?

2011-03-08 Thread Michael Bayer
there's no registry of tables to mappers.   You'd need to track that 
yourself, or otherwise scan through all mappers (non-public attribute 
sqlalchemy.orm._mapper_registry)  looking for tables (each mapper has a 
.local_table attribute).   Note that many mappers can be created against a 
single table.

To track yourself:

from sqlalchemy.orm import mapper as _mapper
import collections

my_registry_of_tables = collections.defaultdict(set)
def mapper(cls, table=None, *arg, **kw):
my_registry_of_tables[table].add(cls)
return _mapper(cls, table, *arg, **kw)

from sqlalchemy.ext.declarative import declarative_base
Base = declarative_base(mapper=mapper)



On Mar 7, 2011, at 11:51 PM, James Mills wrote:

 Hello,
 
 Given a scenario where you're using declarative_base(...) and defining classes
 
 Is there a way to ask SA what the mapper class (declarative) is for a given 
 table
 by inspecting something in metadata[table_name] ?
 
 cheers
 James
 
 
 
 -- 
 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.



Re: [sqlalchemy] Declarative Class registry ?

2011-03-08 Thread James Mills
On Wed, Mar 9, 2011 at 2:16 AM, Michael Bayer mike...@zzzcomputing.com wrote:
 there's no registry of tables to mappers.   You'd need to track that 
 yourself, or otherwise scan through all mappers (non-public attribute 
 sqlalchemy.orm._mapper_registry)  looking for tables (each mapper has a 
 .local_table attribute).   Note that many mappers can be created against a 
 single table.

 To track yourself:

 from sqlalchemy.orm import mapper as _mapper
 import collections

 my_registry_of_tables = collections.defaultdict(set)
 def mapper(cls, table=None, *arg, **kw):
    my_registry_of_tables[table].add(cls)
    return _mapper(cls, table, *arg, **kw)

 from sqlalchemy.ext.declarative import declarative_base
 Base = declarative_base(mapper=mapper)

Thanks Michael.

cheers
James

-- 
-- James Mills
--
-- Problems are solved by method

-- 
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] Declarative Class registry ?

2011-03-07 Thread James Mills
Hello,

Given a scenario where you're using declarative_base(...) and defining 
classes

Is there a way to ask SA what the mapper class (declarative) is for a given 
table
by inspecting something in metadata[table_name] ?

cheers
James


-- 
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] Declarative, Imports and Base

2011-02-08 Thread Martijn Moeling
Hi,

I am having a small issue with multiple python modules and declarative...

I might miss something but

Consider:

a.py:

8---
Base = declarative_base()

class A(Base):
...
8---

b.py
Base = declarative_base()

class B(Base):
...
8---

c.py
Base = declarative_base()

class C(Base):
...
8---

d.py

Base = declarative_base()

from A import * # imports base 
from B import * # imports base
from C import * # imports base

Class D1(Base)
...

Class D2(A)
...


in d.py I want to create:

def create_tables(engine):
metadata= Base.metadata
metadata.create_all(engine)


Is there any way to properly add the metadata from the imported modules in 
d.py  to the Base.metadata during the import..?
Think of modules a,b,c and d are together in a package and d is imported with 
similar packages into something bigger

Martijn








-- 
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] Declarative, Imports and Base

2011-02-08 Thread Michael Bayer

On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote:

 Hi,
 
 I am having a small issue with multiple python modules and declarative...
 
 I might miss something but
 
 Consider:
 
 a.py:
 
 8---
 Base = declarative_base()
 
 class A(Base):
   ...
 8---
 
 b.py
 Base = declarative_base()
 
 class B(Base):
   ...
 8---
 
 c.py
 Base = declarative_base()
 
 class C(Base):
   ...
 8---
 
 d.py
 
 Base = declarative_base()
 
 from A import * # imports base 
 from B import * # imports base
 from C import * # imports base
 
 Class D1(Base)
 ...
 
 Class D2(A)
 ...
 
 
 in d.py I want to create:
 
 def create_tables(engine):
   metadata= Base.metadata
   metadata.create_all(engine)
 
 
 Is there any way to properly add the metadata from the imported modules in 
 d.py  to the Base.metadata during the import..?
 Think of modules a,b,c and d are together in a package and d is imported with 
 similar packages into something bigger

Usually the convention is that all modules in an application share the same 
declarative base object (i.e. Base).   If you wanted multiple Base objects but 
have them share a common MetaData, you can declare the MetaData up front, then 
create each Base using declarative_base(metadata=my_metadata). Otherwise if 
you're really looking to merge together multiple MetaData objects, that's not 
really in the API right now in a clean way, you'd perhaps call .tometadata() on 
each Table object but that's really not what I would do here - it copies the 
whole Table object and isn't really for a use case like this.   If you can at 
least have a common MetaData object, or better a common Base object, that would 
be the best way to go.


-- 
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] Declarative, Imports and Base

2011-02-08 Thread Martijn Moeling
Michael,

Do you ever sleep?

I am not sure I get your point. How do I set up a common Base. 

I could do Base= Declarative_base()

from a import A (or * not sure how this differs in this case)
from b import B (or *)

If I do not declare Base in module a I get an Import Error on class A(Base), 
the same for importing b. 

This gets even more complicated when Base should be build from classes defined 
across modules.

at the end there is one main.py importing all modules and this should be able 
to define the Main Base.

Any suggestions on how to tackle this. I know have multiple modules and am 
glueing everything together. This even gets more problematic with Inheritance.

one solution could be..

from a import A, BaseA 
from b import B, BaseB

Base = declarative_base() 

metadata - BaseA.metadata + BaseB.metadata
metadata.create_all(engine)

What I do not get is how the mapper is configured. Normally with declarative 
Base it is not used in Production fase for as far as I can see.
The mapper is part of the Class right? and session does not use Base at all? 
but gets it when needed - Session.query(A). ?
Or am I totally wrong on this?

Can I something like this:

from a import * (imports class A and the declarative_base BaseA)

Base = declarative_base()

class C(Base):
  ...

BaseForB = declarative_base(metadata=BaseA)
class B(BaseForB)


Mixin classes are of type object so there is no issue since @declared_attr etc 
works

class D(Base,mixinclass) works without a Base at all so there is no Issue

Am I right? in understanding your comments on my first mail in this topic?

Martijn







On Feb 8, 2011, at 7:46 PM, Michael Bayer wrote:

 
 On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote:
 
 Hi,
 
 I am having a small issue with multiple python modules and declarative...
 
 I might miss something but
 
 Consider:
 
 a.py:
 
 8---
 Base = declarative_base()
 
 class A(Base):
  ...
 8---
 
 b.py
 Base = declarative_base()
 
 class B(Base):
  ...
 8---
 
 c.py
 Base = declarative_base()
 
 class C(Base):
  ...
 8---
 
 d.py
 
 Base = declarative_base()
 
 from A import * # imports base 
 from B import * # imports base
 from C import * # imports base
 
 Class D1(Base)
 ...
 
 Class D2(A)
 ...
 
 
 in d.py I want to create:
 
 def create_tables(engine):
  metadata= Base.metadata
  metadata.create_all(engine)
 
 
 Is there any way to properly add the metadata from the imported modules in 
 d.py  to the Base.metadata during the import..?
 Think of modules a,b,c and d are together in a package and d is imported 
 with similar packages into something bigger
 
 Usually the convention is that all modules in an application share the same 
 declarative base object (i.e. Base).   If you wanted multiple Base objects 
 but have them share a common MetaData, you can declare the MetaData up front, 
 then create each Base using declarative_base(metadata=my_metadata). 
 Otherwise if you're really looking to merge together multiple MetaData 
 objects, that's not really in the API right now in a clean way, you'd perhaps 
 call .tometadata() on each Table object but that's really not what I would do 
 here - it copies the whole Table object and isn't really for a use case like 
 this.   If you can at least have a common MetaData object, or better a common 
 Base object, that would be the best way to go.
 
 
 -- 
 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.



Re: [sqlalchemy] Declarative, Imports and Base

2011-02-08 Thread Chris Withers

Hi Martin,

On 08/02/2011 19:25, Martijn Moeling wrote:


I am not sure I get your point. How do I set up a common Base.

I could do Base= Declarative_base()

from a import A (or * not sure how this differs in this case)
from b import B (or *)

If I do not declare Base in module a I get an Import Error on class A(Base), 
the same for importing b.


The answer is you define your base somewhere and have both a and b 
import it from there.



This gets even more complicated when Base should be build from classes defined 
across modules.


...and then even more so when one base needs to be shared between 
multiple python packages ;-)



Any suggestions on how to tackle this.


I have a package I'm itching to release which will help with this.
Keep your eyes open for 'mortar_rdb' ;-)
(it's currently blocked on sqlalchemy-migrate getting a release and me 
doing some renaming from it's customer-specific internal name...)


cheers,

Chris

--
Simplistix - Content Management, Batch Processing  Python Consulting
   - http://www.simplistix.co.uk

--
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] Declarative, Imports and Base

2011-02-08 Thread Michael Bayer
the idea is like this:

myproject/
myproject/__init__.py
myproject/meta.py
myproject/somepackage/__init__.py
myproject/somepackage/a.py
myproject/someotherpackage/__init__.py
myproject/someotherpackage/b.py

myproject/__init__.py:

from myproject.somepackage import a
from myproject.someotherpackage import b

meta.py:

Base = declarative_base()

a.py:

from myproject.meta import Base

b.py:

from myproject.meta import Base










On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote:

 Michael,
 
 Do you ever sleep?
 
 I am not sure I get your point. How do I set up a common Base. 
 
 I could do Base= Declarative_base()
 
 from a import A (or * not sure how this differs in this case)
 from b import B (or *)
 
 If I do not declare Base in module a I get an Import Error on class 
 A(Base), the same for importing b. 
 
 This gets even more complicated when Base should be build from classes 
 defined across modules.
 
 at the end there is one main.py importing all modules and this should be able 
 to define the Main Base.
 
 Any suggestions on how to tackle this. I know have multiple modules and am 
 glueing everything together. This even gets more problematic with Inheritance.
 
 one solution could be..
 
 from a import A, BaseA 
 from b import B, BaseB
 
 Base = declarative_base() 
 
 metadata - BaseA.metadata + BaseB.metadata
 metadata.create_all(engine)
 
 What I do not get is how the mapper is configured. Normally with declarative 
 Base it is not used in Production fase for as far as I can see.
 The mapper is part of the Class right? and session does not use Base at all? 
 but gets it when needed - Session.query(A). ?
 Or am I totally wrong on this?
 
 Can I something like this:
 
 from a import * (imports class A and the declarative_base BaseA)
 
 Base = declarative_base()
 
 class C(Base):
  ...
 
 BaseForB = declarative_base(metadata=BaseA)
 class B(BaseForB)
 
 
 Mixin classes are of type object so there is no issue since @declared_attr 
 etc works
 
 class D(Base,mixinclass) works without a Base at all so there is no Issue
 
 Am I right? in understanding your comments on my first mail in this topic?
 
 Martijn
 
 
 
 
 
 
 
 On Feb 8, 2011, at 7:46 PM, Michael Bayer wrote:
 
 
 On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote:
 
 Hi,
 
 I am having a small issue with multiple python modules and declarative...
 
 I might miss something but
 
 Consider:
 
 a.py:
 
 8---
 Base = declarative_base()
 
 class A(Base):
 ...
 8---
 
 b.py
 Base = declarative_base()
 
 class B(Base):
 ...
 8---
 
 c.py
 Base = declarative_base()
 
 class C(Base):
 ...
 8---
 
 d.py
 
 Base = declarative_base()
 
 from A import * # imports base 
 from B import * # imports base
 from C import * # imports base
 
 Class D1(Base)
 ...
 
 Class D2(A)
 ...
 
 
 in d.py I want to create:
 
 def create_tables(engine):
 metadata= Base.metadata
 metadata.create_all(engine)
 
 
 Is there any way to properly add the metadata from the imported modules 
 in d.py  to the Base.metadata during the import..?
 Think of modules a,b,c and d are together in a package and d is imported 
 with similar packages into something bigger
 
 Usually the convention is that all modules in an application share the same 
 declarative base object (i.e. Base).   If you wanted multiple Base objects 
 but have them share a common MetaData, you can declare the MetaData up 
 front, then create each Base using declarative_base(metadata=my_metadata).   
   Otherwise if you're really looking to merge together multiple MetaData 
 objects, that's not really in the API right now in a clean way, you'd 
 perhaps call .tometadata() on each Table object but that's really not what I 
 would do here - it copies the whole Table object and isn't really for a use 
 case like this.   If you can at least have a common MetaData object, or 
 better a common Base object, that would be the best way to go.
 
 
 -- 
 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.
 

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

Re: [sqlalchemy] Declarative, Imports and Base

2011-02-08 Thread Martijn Moeling
Clear, if all packages are in the same project that is..

and what if in a.py I want to inherit some class mapped with b.py  

mixin does not allways work as a solution subclassing (DeclarativeMeta) is an 
option, not sure

Once I do a base=declarative_base(metadata=BaseB)

every class x(Base) gets the Columns in BaseB to it ..?

I have been setting up some tests and one way or the other I need to know how 
Session is using Base, if I can have multiple declarative_base instances and 
how Session relates to that.


Consider this:

Base = Declarative_base()

class a(Base):




def create_table(engine):
b=a()
metadata = b.metadata
metadata.create_all(engine)

Base = None  # IMPORTANT IS Sessionmaker using intropsection to find out an 
instance of Declarative base?

engine = 
Session = SessionMaker(bind=engine)

would this or a  similar approach work?


On Feb 8, 2011, at 9:12 PM, Michael Bayer wrote:

 the idea is like this:
 
 myproject/
 myproject/__init__.py
 myproject/meta.py
 myproject/somepackage/__init__.py
 myproject/somepackage/a.py
 myproject/someotherpackage/__init__.py
 myproject/someotherpackage/b.py
 
 myproject/__init__.py:
 
 from myproject.somepackage import a
 from myproject.someotherpackage import b
 
 meta.py:
 
 Base = declarative_base()
 
 a.py:
 
 from myproject.meta import Base
 
 b.py:
 
 from myproject.meta import Base
 
 
 
 
 
 
 
 
 
 
 On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote:
 
 Michael,
 
 Do you ever sleep?
 
 I am not sure I get your point. How do I set up a common Base. 
 
 I could do Base= Declarative_base()
 
 from a import A (or * not sure how this differs in this case)
 from b import B (or *)
 
 If I do not declare Base in module a I get an Import Error on class 
 A(Base), the same for importing b. 
 
 This gets even more complicated when Base should be build from classes 
 defined across modules.
 
 at the end there is one main.py importing all modules and this should be 
 able to define the Main Base.
 
 Any suggestions on how to tackle this. I know have multiple modules and am 
 glueing everything together. This even gets more problematic with 
 Inheritance.
 
 one solution could be..
 
 from a import A, BaseA 
 from b import B, BaseB
 
 Base = declarative_base() 
 
 metadata - BaseA.metadata + BaseB.metadata
 metadata.create_all(engine)
 
 What I do not get is how the mapper is configured. Normally with declarative 
 Base it is not used in Production fase for as far as I can see.
 The mapper is part of the Class right? and session does not use Base at all? 
 but gets it when needed - Session.query(A). ?
 Or am I totally wrong on this?
 
 Can I something like this:
 
 from a import * (imports class A and the declarative_base BaseA)
 
 Base = declarative_base()
 
 class C(Base):
 ...
 
 BaseForB = declarative_base(metadata=BaseA)
 class B(BaseForB)
 
 
 Mixin classes are of type object so there is no issue since @declared_attr 
 etc works
 
 class D(Base,mixinclass) works without a Base at all so there is no Issue
 
 Am I right? in understanding your comments on my first mail in this topic?
 
 Martijn
 
 
 
 
 
 
 
 On Feb 8, 2011, at 7:46 PM, Michael Bayer wrote:
 
 
 On Feb 8, 2011, at 1:19 PM, Martijn Moeling wrote:
 
 Hi,
 
 I am having a small issue with multiple python modules and declarative...
 
 I might miss something but
 
 Consider:
 
 a.py:
 
 8---
 Base = declarative_base()
 
 class A(Base):
...
 8---
 
 b.py
 Base = declarative_base()
 
 class B(Base):
...
 8---
 
 c.py
 Base = declarative_base()
 
 class C(Base):
...
 8---
 
 d.py
 
 Base = declarative_base()
 
 from A import * # imports base 
 from B import * # imports base
 from C import * # imports base
 
 Class D1(Base)
 ...
 
 Class D2(A)
 ...
 
 
 in d.py I want to create:
 
 def create_tables(engine):
metadata= Base.metadata
metadata.create_all(engine)
 
 
 Is there any way to properly add the metadata from the imported modules 
 in d.py  to the Base.metadata during the import..?
 Think of modules a,b,c and d are together in a package and d is imported 
 with similar packages into something bigger
 
 Usually the convention is that all modules in an application share the same 
 declarative base object (i.e. Base).   If you wanted multiple Base objects 
 but have them share a common MetaData, you can declare the MetaData up 
 front, then create each Base using declarative_base(metadata=my_metadata).  
Otherwise if you're really looking to merge together multiple MetaData 
 objects, that's not really in the API right now in a clean way, you'd 
 perhaps call .tometadata() on each Table object but that's really not what 
 I would do here - it copies the whole Table object and isn't really for a 
 use case like this.   If you can at 

Re: [sqlalchemy] Declarative, Imports and Base

2011-02-08 Thread Michael Bayer

On Feb 8, 2011, at 3:57 PM, Martijn Moeling wrote:

 Clear, if all packages are in the same project that is..
 
 and what if in a.py I want to inherit some class mapped with b.py  
 
 mixin does not allways work as a solution subclassing (DeclarativeMeta) is an 
 option, not sure
 
 Once I do a base=declarative_base(metadata=BaseB)
 
 every class x(Base) gets the Columns in BaseB to it ..?
 
 I have been setting up some tests and one way or the other I need to know how 
 Session is using Base, if I can have multiple declarative_base instances and 
 how Session relates to that.
 
 
 Consider this:
 
 Base = Declarative_base()
 
 class a(Base):
   
   
   
 
 def create_table(engine):
   b=a()
   metadata = b.metadata
   metadata.create_all(engine)
 
 Base = None  # IMPORTANT IS Sessionmaker using intropsection to find out 
 an instance of Declarative base?
 
 engine = 
 Session = SessionMaker(bind=engine)
 
 would this or a  similar approach work?

Session does not care about Base, nor does MetaData.

The Base gives you this:

class MyObject(Base):
...
related = relationship(Related)

the string Related is looked up in a dictionary inside of Base.   The 
dictionary is called _decl_class_registry.

MetaData gives you this:

class MyObject(Base):
...
related_id = Column(Integer, ForeignKey('related.id'))

the string 'related.id' is broken into 'related' and 'id' and is looked up 
inside a dictionary inside of MetaData().   The dictionary is called tables.  
  There's some extra lookup helper mechanics surrounding this dictionary in 0.7 
which is why we don't want you manipulating .tables directly.

Those two registries are the *only* thing you get from a Base and a MetaData 
that is dependent on how many of them are in use.   Neither is strictly needed. 
  relationship() accepts the real class itself, i.e. relationship(Related).   
ForeignKey accepts a real column object, i.e. ForeignKey(related_table.c.id).   
 The registries are strictly for the purpose of making it *easier* to organize 
table metadata and declarative classes without worrying about order of 
dependencies, allowing specification of related constructs via string name.  
Otherwise feel free to declare every single class and Table on its own Base and 
MetaData, it makes no difference.

If you have multiple projects each with their own set of unrelated tables, 
there is no need to merge any Base or MetaData objects together.  Simply call 
create_all() on each MetaData() object as needed.   The namespaces remain 
entirely separate, as they should.

If OTOH the multiple projects are linking to each other's tables and classes, 
then these projects have a dependency on each other.  You should change them 
such that a common MetaData, and optionally a Base, can be specified from which 
they all make usage of - unless you can get away with not declaring any 
inter-package relationships or foreign keys with string names.









 
 
 On Feb 8, 2011, at 9:12 PM, Michael Bayer wrote:
 
 the idea is like this:
 
 myproject/
 myproject/__init__.py
 myproject/meta.py
 myproject/somepackage/__init__.py
 myproject/somepackage/a.py
 myproject/someotherpackage/__init__.py
 myproject/someotherpackage/b.py
 
 myproject/__init__.py:
 
 from myproject.somepackage import a
 from myproject.someotherpackage import b
 
 meta.py:
 
 Base = declarative_base()
 
 a.py:
 
 from myproject.meta import Base
 
 b.py:
 
 from myproject.meta import Base
 
 
 
 
 
 
 
 
 
 
 On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote:
 
 Michael,
 
 Do you ever sleep?
 
 I am not sure I get your point. How do I set up a common Base. 
 
 I could do Base= Declarative_base()
 
 from a import A (or * not sure how this differs in this case)
 from b import B (or *)
 
 If I do not declare Base in module a I get an Import Error on class 
 A(Base), the same for importing b. 
 
 This gets even more complicated when Base should be build from classes 
 defined across modules.
 
 at the end there is one main.py importing all modules and this should be 
 able to define the Main Base.
 
 Any suggestions on how to tackle this. I know have multiple modules and am 
 glueing everything together. This even gets more problematic with 
 Inheritance.
 
 one solution could be..
 
 from a import A, BaseA 
 from b import B, BaseB
 
 Base = declarative_base() 
 
 metadata - BaseA.metadata + BaseB.metadata
 metadata.create_all(engine)
 
 What I do not get is how the mapper is configured. Normally with 
 declarative Base it is not used in Production fase for as far as I can 
 see.
 The mapper is part of the Class right? and session does not use Base at 
 all? but gets it when needed - Session.query(A). ?
 Or am I totally wrong on this?
 
 Can I something like this:
 
 from a import * (imports class A and the declarative_base BaseA)
 
 Base = declarative_base()
 
 class C(Base):
...
 
 BaseForB = declarative_base(metadata=BaseA)
 

Re: [sqlalchemy] Declarative, Imports and Base

2011-02-08 Thread Martijn Moeling
Clear!


On Feb 8, 2011, at 10:21 PM, Michael Bayer wrote:

 
 On Feb 8, 2011, at 3:57 PM, Martijn Moeling wrote:
 
 Clear, if all packages are in the same project that is..
 
 and what if in a.py I want to inherit some class mapped with b.py  
 
 mixin does not allways work as a solution subclassing (DeclarativeMeta) is 
 an option, not sure
 
 Once I do a base=declarative_base(metadata=BaseB)
 
 every class x(Base) gets the Columns in BaseB to it ..?
 
 I have been setting up some tests and one way or the other I need to know 
 how Session is using Base, if I can have multiple declarative_base instances 
 and how Session relates to that.
 
 
 Consider this:
 
 Base = Declarative_base()
 
 class a(Base):
  
  
  
 
 def create_table(engine):
  b=a()
  metadata = b.metadata
  metadata.create_all(engine)
 
 Base = None  # IMPORTANT IS Sessionmaker using intropsection to find out 
 an instance of Declarative base?
 
 engine = 
 Session = SessionMaker(bind=engine)
 
 would this or a  similar approach work?
 
 Session does not care about Base, nor does MetaData.
 
 The Base gives you this:
 
 class MyObject(Base):
...
related = relationship(Related)
 
 the string Related is looked up in a dictionary inside of Base.   The 
 dictionary is called _decl_class_registry.
 
 MetaData gives you this:
 
 class MyObject(Base):
...
related_id = Column(Integer, ForeignKey('related.id'))
 
 the string 'related.id' is broken into 'related' and 'id' and is looked up 
 inside a dictionary inside of MetaData().   The dictionary is called 
 tables.There's some extra lookup helper mechanics surrounding this 
 dictionary in 0.7 which is why we don't want you manipulating .tables 
 directly.
 
 Those two registries are the *only* thing you get from a Base and a MetaData 
 that is dependent on how many of them are in use.   Neither is strictly 
 needed.   relationship() accepts the real class itself, i.e. 
 relationship(Related).   ForeignKey accepts a real column object, i.e. 
 ForeignKey(related_table.c.id).The registries are strictly for the 
 purpose of making it *easier* to organize table metadata and declarative 
 classes without worrying about order of dependencies, allowing specification 
 of related constructs via string name.  Otherwise feel free to declare every 
 single class and Table on its own Base and MetaData, it makes no difference.
 
 If you have multiple projects each with their own set of unrelated tables, 
 there is no need to merge any Base or MetaData objects together.  Simply call 
 create_all() on each MetaData() object as needed.   The namespaces remain 
 entirely separate, as they should.
 
 If OTOH the multiple projects are linking to each other's tables and classes, 
 then these projects have a dependency on each other.  You should change them 
 such that a common MetaData, and optionally a Base, can be specified from 
 which they all make usage of - unless you can get away with not declaring any 
 inter-package relationships or foreign keys with string names.
 
 
 
 
 
 
 
 
 
 
 
 On Feb 8, 2011, at 9:12 PM, Michael Bayer wrote:
 
 the idea is like this:
 
 myproject/
 myproject/__init__.py
 myproject/meta.py
 myproject/somepackage/__init__.py
 myproject/somepackage/a.py
 myproject/someotherpackage/__init__.py
 myproject/someotherpackage/b.py
 
 myproject/__init__.py:
 
 from myproject.somepackage import a
 from myproject.someotherpackage import b
 
 meta.py:
 
 Base = declarative_base()
 
 a.py:
 
 from myproject.meta import Base
 
 b.py:
 
 from myproject.meta import Base
 
 
 
 
 
 
 
 
 
 
 On Feb 8, 2011, at 2:25 PM, Martijn Moeling wrote:
 
 Michael,
 
 Do you ever sleep?
 
 I am not sure I get your point. How do I set up a common Base. 
 
 I could do Base= Declarative_base()
 
 from a import A (or * not sure how this differs in this case)
 from b import B (or *)
 
 If I do not declare Base in module a I get an Import Error on class 
 A(Base), the same for importing b. 
 
 This gets even more complicated when Base should be build from classes 
 defined across modules.
 
 at the end there is one main.py importing all modules and this should be 
 able to define the Main Base.
 
 Any suggestions on how to tackle this. I know have multiple modules and am 
 glueing everything together. This even gets more problematic with 
 Inheritance.
 
 one solution could be..
 
 from a import A, BaseA 
 from b import B, BaseB
 
 Base = declarative_base() 
 
 metadata - BaseA.metadata + BaseB.metadata
 metadata.create_all(engine)
 
 What I do not get is how the mapper is configured. Normally with 
 declarative Base it is not used in Production fase for as far as I can 
 see.
 The mapper is part of the Class right? and session does not use Base at 
 all? but gets it when needed - Session.query(A). ?
 Or am I totally wrong on this?
 
 Can I something like this:
 
 from a import * (imports class A and the declarative_base BaseA)

Re: [sqlalchemy] declarative one to many relationship with composite primary key

2010-11-17 Thread Adrien Saladin
On Wed, Nov 17, 2010 at 1:16 AM, Michael Bayer mike...@zzzcomputing.com wrote:
 ForeignKeyConstraint needs to go into __table_args__ when using declarative.

 http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#table-configuration

Thanks for the note. I have updated my test script to use
__table_args__  but the error remains the same (see script and ouput
below).

I then tried with the hybrid approach
(http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#using-a-hybrid-approach-with-table)
which works well.
Am I again doing something wrong with declarative ?

Thanks,


#
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative  import declarative_base


Base = declarative_base()

class Foo(Base):
   __tablename__ = foo
   one = Column(Integer, primary_key=True)
   two = Column(Integer, primary_key=True)

class Bar(Base):
   __tablename__ = bar
   __table_args__ = (  ForeignKeyConstraint(['one_id', 'two_id'],
['foo.one', 'foo.two']) )
   id = Column(Integer, primary_key=True)
   one_id = Column(Integer, nullable=False)
   two_id = Column(Integer, nullable=False)

   foo = relationship(Foo, backref = bars)



metadata = Base.metadata

engine = create_engine('sqlite:///:memory:', echo=True)
metadata.create_all(engine)

from sqlalchemy.orm import sessionmaker

# create a configured Session class
Session = sessionmaker(bind=engine)

# create a Session
session = Session()

foo = Foo()
foo.one = 1
foo.two = 2
session.add(foo)
session.commit()

#



2010-11-17 14:56:01,309 INFO sqlalchemy.engine.base.Engine.0x...9690
PRAGMA table_info(foo)
2010-11-17 14:56:01,309 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690
PRAGMA table_info(bar)
2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690
CREATE TABLE foo (
one INTEGER NOT NULL,
two INTEGER NOT NULL,
PRIMARY KEY (one, two)
)


2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 COMMIT
2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690
CREATE TABLE bar (
id INTEGER NOT NULL,
one_id INTEGER NOT NULL,
two_id INTEGER NOT NULL,
PRIMARY KEY (id)
)


2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690 COMMIT
Traceback (most recent call last):
  File compositePrimaryKey_decl.py, line 39, in module
foo = Foo()
  File string, line 4, in __init__
  File 
/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/state.py,
line 93, in initialize_instance
fn(self, instance, args, kwargs)
  File 
/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py,
line 2357, in _event_on_init
instrumenting_mapper.compile()
  File 
/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py,
line 805, in compile
mapper._post_configure_properties()
  File 
/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py,
line 834, in _post_configure_properties
prop.init()
  File 
/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/interfaces.py,
line 493, in init
self.do_init()
  File 
/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/properties.py,
line 840, in do_init
self._determine_joins()
  File 
/home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/properties.py,
line 969, in _determine_joins
% self)
sqlalchemy.exc.ArgumentError: Could not determine join condition
between parent/child tables on relationship Bar.foo.  Specify a
'primaryjoin' expression.  If this is a many-to-many relationship,
'secondaryjoin' is needed as well.


The script below works with the hybrid declarative approach:

#
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative  import declarative_base


Base = declarative_base()

class Foo(Base):
   __tablename__ = foo
   one = Column(Integer, primary_key=True)
   two = Column(Integer, primary_key=True)



bartable = Table(bar, Base.metadata,
   Column(id, Integer, primary_key=True),
   Column(one_id, Integer, nullable=False),
   Column(two_id, Integer, nullable=False),
   ForeignKeyConstraint(['one_id', 'two_id'], ['foo.one', 'foo.two']),
)




class Bar(Base):
   __table__ = bartable
   foo = relationship(Foo, backref = bars)


metadata = Base.metadata

engine = create_engine('sqlite:///:memory:', echo=True)
metadata.create_all(engine)

from sqlalchemy.orm import sessionmaker

# create a configured Session class
Session = sessionmaker(bind=engine)

# create a Session
session = Session()

foo = Foo()
foo.one = 1
foo.two = 2

Re: [sqlalchemy] declarative one to many relationship with composite primary key

2010-11-17 Thread Michael Bayer

On Nov 17, 2010, at 9:07 AM, Adrien Saladin wrote:

 On Wed, Nov 17, 2010 at 1:16 AM, Michael Bayer mike...@zzzcomputing.com 
 wrote:
 ForeignKeyConstraint needs to go into __table_args__ when using declarative.
 
 http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#table-configuration
 
 Thanks for the note. I have updated my test script to use
 __table_args__  but the error remains the same (see script and ouput
 below).

OK its actually a huge SQLA bug that an error isn't raised for that, which is 
surprising to me, so I created and resolved #1972 in r67d8f4e2fcb9.   
__table_args__ is expected to be a tuple or dict, so now an error is raised if 
it's not.   (x) isn't a tuple.   

here's the correct form:

class Bar(Base):
  __tablename__ = bar
  __table_args__ = (  ForeignKeyConstraint(['one_id', 'two_id'], ['foo.one', 
'foo.two']),{} )
  id = Column(Integer, primary_key=True)
  one_id = Column(Integer, nullable=False)
  two_id = Column(Integer, nullable=False)

  foo = relationship(Foo, backref = bars)



 
 I then tried with the hybrid approach
 (http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#using-a-hybrid-approach-with-table)
 which works well.
 Am I again doing something wrong with declarative ?
 
 Thanks,
 
 
 #
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative  import declarative_base
 
 
 Base = declarative_base()
 
 class Foo(Base):
   __tablename__ = foo
   one = Column(Integer, primary_key=True)
   two = Column(Integer, primary_key=True)
 
 class Bar(Base):
   __tablename__ = bar
   __table_args__ = (  ForeignKeyConstraint(['one_id', 'two_id'],
 ['foo.one', 'foo.two']) )
   id = Column(Integer, primary_key=True)
   one_id = Column(Integer, nullable=False)
   two_id = Column(Integer, nullable=False)
 
   foo = relationship(Foo, backref = bars)
 
 
 
 metadata = Base.metadata
 
 engine = create_engine('sqlite:///:memory:', echo=True)
 metadata.create_all(engine)
 
 from sqlalchemy.orm import sessionmaker
 
 # create a configured Session class
 Session = sessionmaker(bind=engine)
 
 # create a Session
 session = Session()
 
 foo = Foo()
 foo.one = 1
 foo.two = 2
 session.add(foo)
 session.commit()
 
 #
 
 
 
 2010-11-17 14:56:01,309 INFO sqlalchemy.engine.base.Engine.0x...9690
 PRAGMA table_info(foo)
 2010-11-17 14:56:01,309 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690
 PRAGMA table_info(bar)
 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690
 CREATE TABLE foo (
one INTEGER NOT NULL,
two INTEGER NOT NULL,
PRIMARY KEY (one, two)
 )
 
 
 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
 2010-11-17 14:56:01,310 INFO sqlalchemy.engine.base.Engine.0x...9690 COMMIT
 2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690
 CREATE TABLE bar (
id INTEGER NOT NULL,
one_id INTEGER NOT NULL,
two_id INTEGER NOT NULL,
PRIMARY KEY (id)
 )
 
 
 2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690 ()
 2010-11-17 14:56:01,311 INFO sqlalchemy.engine.base.Engine.0x...9690 COMMIT
 Traceback (most recent call last):
  File compositePrimaryKey_decl.py, line 39, in module
foo = Foo()
  File string, line 4, in __init__
  File 
 /home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/state.py,
 line 93, in initialize_instance
fn(self, instance, args, kwargs)
  File 
 /home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py,
 line 2357, in _event_on_init
instrumenting_mapper.compile()
  File 
 /home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py,
 line 805, in compile
mapper._post_configure_properties()
  File 
 /home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/mapper.py,
 line 834, in _post_configure_properties
prop.init()
  File 
 /home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/interfaces.py,
 line 493, in init
self.do_init()
  File 
 /home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/properties.py,
 line 840, in do_init
self._determine_joins()
  File 
 /home/virtualenvs/sqlalchemy/lib/python2.6/site-packages/sqlalchemy/orm/properties.py,
 line 969, in _determine_joins
% self)
 sqlalchemy.exc.ArgumentError: Could not determine join condition
 between parent/child tables on relationship Bar.foo.  Specify a
 'primaryjoin' expression.  If this is a many-to-many relationship,
 'secondaryjoin' is needed as well.
 
 
 The script below works with the hybrid declarative approach:
 
 #
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative  import declarative_base
 
 
 Base = declarative_base()
 
 class 

Re: [sqlalchemy] declarative one to many relationship with composite primary key

2010-11-17 Thread Adrien Saladin
On Wed, Nov 17, 2010 at 4:58 PM, Michael Bayer mike...@zzzcomputing.com wrote:
 OK its actually a huge SQLA bug that an error isn't raised for that, which is 
 surprising to me, so I created and resolved #1972 in r67d8f4e2fcb9.   
 __table_args__ is expected to be a tuple or dict, so now an error is raised 
 if it's not.   (x) isn't a tuple.


Thanks for the quick reply, the patch and the syntax correction of my code.

Regards,

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] declarative one to many relationship with composite primary key

2010-11-16 Thread Adrien
Hi list,

Sorry if this is trivial, I'm relatively new to sqlalchemy.
I'm trying to set a one to many relationship between class Foo and
class Bar (ie Foo should have a list of Bars). Foo has a composite
primary key.

#
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative  import declarative_base


Base = declarative_base()

class Foo(Base):
__tablename__ = foo
one = Column(Integer, primary_key=True)
two = Column(Integer, primary_key=True)

class Bar(Base):
__tablename__ = bar
id = Column(Integer, primary_key=True)
one_id = Column(Integer, nullable=False)
two_id = Column(Integer, nullable=False)

ForeignKeyConstraint([one_id, two_id], [foo.one, foo.two])
foo = relationship(Foo, backref = bars)


metadata = Base.metadata

engine = create_engine('sqlite:///:memory:', echo=True)
metadata.create_all(engine)

from sqlalchemy.orm import sessionmaker

# create a configured Session class
Session = sessionmaker(bind=engine)

# create a Session
session = Session()

foo = Foo()
foo.one = 1
foo.two = 2
session.add(foo)
session.commit()
#

I get the following message:

sqlalchemy.exc.ArgumentError: Could not determine join condition
between parent/child tables on relationship Bar.foo.  Specify a
'primaryjoin' expression.


I tried to change the relationship line to:
foo = relationship(Foo, backref = bars, primaryjoin=and_(one_id ==
Foo.one, two_id==Foo.two ) )

but then I get this message:

sqlalchemy.exc.ArgumentError: Could not determine relationship
direction for primaryjoin condition 'bar.one_id = foo.one AND
bar.two_id = foo.two', on relationship Bar.foo. Ensure that the
referencing Column objects have a ForeignKey present, or are otherwise
part of a ForeignKeyConstraint on their parent Table.

Thank you for your help!

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] declarative one to many relationship with composite primary key

2010-11-16 Thread Michael Bayer
ForeignKeyConstraint needs to go into __table_args__ when using declarative.

http://www.sqlalchemy.org/docs/orm/extensions/declarative.html#table-configuration


On Nov 16, 2010, at 6:28 PM, Adrien wrote:

 Hi list,
 
 Sorry if this is trivial, I'm relatively new to sqlalchemy.
 I'm trying to set a one to many relationship between class Foo and
 class Bar (ie Foo should have a list of Bars). Foo has a composite
 primary key.
 
 #
 from sqlalchemy import *
 from sqlalchemy.orm import *
 from sqlalchemy.ext.declarative  import declarative_base
 
 
 Base = declarative_base()
 
 class Foo(Base):
__tablename__ = foo
one = Column(Integer, primary_key=True)
two = Column(Integer, primary_key=True)
 
 class Bar(Base):
__tablename__ = bar
id = Column(Integer, primary_key=True)
one_id = Column(Integer, nullable=False)
two_id = Column(Integer, nullable=False)
 
ForeignKeyConstraint([one_id, two_id], [foo.one, foo.two])
foo = relationship(Foo, backref = bars)
 
 
 metadata = Base.metadata
 
 engine = create_engine('sqlite:///:memory:', echo=True)
 metadata.create_all(engine)
 
 from sqlalchemy.orm import sessionmaker
 
 # create a configured Session class
 Session = sessionmaker(bind=engine)
 
 # create a Session
 session = Session()
 
 foo = Foo()
 foo.one = 1
 foo.two = 2
 session.add(foo)
 session.commit()
 #
 
 I get the following message:
 
 sqlalchemy.exc.ArgumentError: Could not determine join condition
 between parent/child tables on relationship Bar.foo.  Specify a
 'primaryjoin' expression.
 
 
 I tried to change the relationship line to:
 foo = relationship(Foo, backref = bars, primaryjoin=and_(one_id ==
 Foo.one, two_id==Foo.two ) )
 
 but then I get this message:
 
 sqlalchemy.exc.ArgumentError: Could not determine relationship
 direction for primaryjoin condition 'bar.one_id = foo.one AND
 bar.two_id = foo.two', on relationship Bar.foo. Ensure that the
 referencing Column objects have a ForeignKey present, or are otherwise
 part of a ForeignKeyConstraint on their parent Table.
 
 Thank you for your help!
 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@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] declarative - automatically add a primary key if the table doesn't have one

2010-09-22 Thread Yap Sok Ann
This is related to topic need 0.6_beta2-compat declarative meta
http://groups.google.com/group/sqlalchemy/browse_thread/thread/ae7cb9d2ab0b9cca

Prior to version 0.6, I use the following code to automatically add a
primary key if the table doesn't have one defined:

from sqlalchemy.ext.declarative import declarative_base,
DeclarativeMeta
from sqlalchemy.schema import Column
from sqlalchemy.types import Integer

class Meta(DeclarativeMeta):
def __init__(cls, classname, bases, dict_):
for attr in dict_.itervalues():
if isinstance(attr, Column) and attr.primary_key:
break
else:
dict_['id'] = Column(Integer, primary_key=True)
return super(Meta, cls).__init__(classname, bases, dict_)

Base = declarative_base(metaclass=Meta)

Of course, that doesn't work anymore in 0.6. The suggestion from the
aforementioned threads is to replace:

dict_['id'] = Column(Integer, primary_key=True)

with

cls.id = Column(Integer, primary_key=True)

Unfortunately, that alone doesn't work in this case. The problem is
that the Base class itself will be the first one to go through the
Meta.__init__() method, so the whole thing essentially becomes:

Base.id = Column(Integer, primary_key=True)

For it to work, I have to wrap the code in an if-block, i.e.

class Meta(DeclarativeMeta):
def __init__(cls, classname, bases, dict_):
if classname != 'Base':
for attr in dict_.itervalues():
if isinstance(attr, Column) and attr.primary_key:
break
else:
cls.id = Column(Integer, primary_key=True)
return super(Meta, cls).__init__(classname, bases, dict_)

which looks rather ugly. Is there a cleaner way to achieve this?

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] declarative - automatically add a primary key if the table doesn't have one

2010-09-22 Thread Michael Bayer

On Sep 22, 2010, at 4:30 AM, Yap Sok Ann wrote:

 This is related to topic need 0.6_beta2-compat declarative meta
 http://groups.google.com/group/sqlalchemy/browse_thread/thread/ae7cb9d2ab0b9cca
 
 Prior to version 0.6, I use the following code to automatically add a
 primary key if the table doesn't have one defined:
 
 from sqlalchemy.ext.declarative import declarative_base,
 DeclarativeMeta
 from sqlalchemy.schema import Column
 from sqlalchemy.types import Integer
 
 class Meta(DeclarativeMeta):
def __init__(cls, classname, bases, dict_):
for attr in dict_.itervalues():
if isinstance(attr, Column) and attr.primary_key:
break
else:
dict_['id'] = Column(Integer, primary_key=True)
return super(Meta, cls).__init__(classname, bases, dict_)
 
 Base = declarative_base(metaclass=Meta)
 
 Of course, that doesn't work anymore in 0.6. The suggestion from the
 aforementioned threads is to replace:
 
 dict_['id'] = Column(Integer, primary_key=True)
 
 with
 
 cls.id = Column(Integer, primary_key=True)
 
 Unfortunately, that alone doesn't work in this case. The problem is
 that the Base class itself will be the first one to go through the
 Meta.__init__() method, so the whole thing essentially becomes:
 
 Base.id = Column(Integer, primary_key=True)
 
 For it to work, I have to wrap the code in an if-block, i.e.
 
 class Meta(DeclarativeMeta):
def __init__(cls, classname, bases, dict_):
if classname != 'Base':
for attr in dict_.itervalues():
if isinstance(attr, Column) and attr.primary_key:
break
else:
cls.id = Column(Integer, primary_key=True)
return super(Meta, cls).__init__(classname, bases, dict_)
 
 which looks rather ugly. Is there a cleaner way to achieve this?

I didn't think metaclasses were supposed to be pretty ?Checking that you're 
not the base is pretty standard metaclass stuff.  If the hardcoded name 
is the issue, you can look in bases:

if object not in bases:
 
or something more generic:

for k in cls.__mro__[1:]:
if isinstance(k, Meta):
# you're a Base subclass



 
 -- 
 You received this message because you are subscribed to the Google Groups 
 sqlalchemy group.
 To post to this group, send email to sqlalch...@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 sqlalch...@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] Declarative classproperty member problem in 0.6.4, not 0.6.3

2010-09-15 Thread Nikolaj
The following test fails in 0.6.4 but not 0.6.3 with AttributeError:
type object 'Person' has no attribute 'foo'. Is this a deliberate
change? It seems a bit weird that every @classproperty on a
declarative subclass is accessed/run on import.

from sqlalchemy import create_engine, Column, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.util import classproperty

Base = declarative_base()

class Person(Base):
__tablename__ = 'people'

name = Column(String, primary_key=True)

@classproperty
def bar(cls):
return cls.foo

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] Declarative classproperty member problem in 0.6.4, not 0.6.3

2010-09-15 Thread Michael Bayer

On Sep 15, 2010, at 10:04 AM, Nikolaj wrote:

 The following test fails in 0.6.4 but not 0.6.3 with AttributeError:
 type object 'Person' has no attribute 'foo'. Is this a deliberate
 change? It seems a bit weird that every @classproperty on a
 declarative subclass is accessed/run on import.
 
 from sqlalchemy import create_engine, Column, String
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.util import classproperty
 
 Base = declarative_base()
 
 class Person(Base):
__tablename__ = 'people'
 
name = Column(String, primary_key=True)
 
@classproperty
def bar(cls):
return cls.foo

The backrground for this is deliberate, but the effect you are seeing was not 
originally intended.   Person.foo is being evaluated when Person is first 
created by the declarative base, to see if it returns a mapper property.   If 
.foo isn't available there's your error.

The declarative evaluation is limited to the @classproperty decorator that's 
inside of sqlalchemy.util.   If you use your own external @classproperty it 
won't be called upon.


-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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] Declarative classproperty member problem in 0.6.4, not 0.6.3

2010-09-15 Thread Chris Withers

On 15/09/2010 15:04, Nikolaj wrote:

Base = declarative_base()

class Person(Base):
 __tablename__ = 'people'

 name = Column(String, primary_key=True)

 @classproperty
 def bar(cls):
 return cls.foo


Can you explain why you'd want to do something like this?

Chris

--
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To post to this group, send email to sqlalch...@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.



  1   2   >