[sqlalchemy] alternate way to filter queries
Hi all, This might be a bit of a stretch but here it goes: Say that i have a lambda function that takes a mapped object and teturns whether it is valid; e.g: lambda person: person.age 17 or person.length 1.75 is it possible to use this method to perform an sqla query on the database? Perhaps by using hybrid_method? Cheers, Lars PS: this might seem strange question, but it would save me a lot of work and/or would make my internal and user interfaces a lot more consistent. PPS: i do also have a string representation of the lambda functions, if that helps -- 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] alternate way to filter queries
On Aug 26, 2013, at 11:14 AM, lars van gemerden l...@rational-it.com wrote: Hi all, This might be a bit of a stretch but here it goes: Say that i have a lambda function that takes a mapped object and teturns whether it is valid; e.g: lambda person: person.age 17 or person.length 1.75 is it possible to use this method to perform an sqla query on the database? Perhaps by using hybrid_method? Cheers, Lars PS: this might seem strange question, but it would save me a lot of work and/or would make my internal and user interfaces a lot more consistent. PPS: i do also have a string representation of the lambda functions, if that helps I'm not sure if you need these to remain as lambdas, sure you can just pass it to a hybrid_method: class MyClass(Base): # @hybrid_method def run_compare(self, fn, *args): return fn(*args) query(MyClass).filter(MyClass.run_compare(some_lambda, some_other_object)) -- 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] testing for an association proxy (possible bug and patch included)
On Aug 23, 2013, at 6:34 PM, jason kirtland j...@discorporate.us wrote: The patch seems like surprising Python behavior to me. Traversing across a None is almost certainly a bug in regular code, and quashing that error by default feels dangerous. I would want this to raise by default (and I have found bugs because it did.) I think you could opt into this behavior by supplying an alternate, custom getter function that quashed None when creating the proxy. Looking at the tests in this area, I can see that they expect an error to be raised on scalar access of a None; though the tests in this area have apparently been long broken since we moved to nosetests, where we've lost access to the fail() method. I find it surprising that we would want to raise on a None, because the purpose of association proxy is to proxy access to an attribute. If the underlying attribute is returning None and that's not an error, then the association proxy itself should return None.I've spent some time trying to figure a legitimate error case I'd want raised here, can you provide one ? Otherwise I'm leaning towards having the proxy faithfully proxy out the underlying None and I'd backport that at least to 0.8 if not 0.7. signature.asc Description: Message signed with OpenPGP using GPGMail
Re: [sqlalchemy] alternate way to filter queries
Hi Michael, So just to be sure, if i understand correctly and i have: func = lambda person: person.age 17 or person.length 1.75 I can do: class Person(Base): # @hybrid_method def run_filter(self, fn): return fn(self) session.query(MyClass).filter(MyClass.run_compare(func)) to get all objects of class Person where obj.age17 or obj.length1.75 Is that without loading all records and filtering afterwards?? That's pretty impressive i think (and really helpful to me personally) Cheers, Lars On Monday, August 26, 2013 5:23:07 PM UTC+2, Michael Bayer wrote: On Aug 26, 2013, at 11:14 AM, lars van gemerden la...@rational-it.comjavascript: wrote: Hi all, This might be a bit of a stretch but here it goes: Say that i have a lambda function that takes a mapped object and teturns whether it is valid; e.g: lambda person: person.age 17 or person.length 1.75 is it possible to use this method to perform an sqla query on the database? Perhaps by using hybrid_method? Cheers, Lars PS: this might seem strange question, but it would save me a lot of work and/or would make my internal and user interfaces a lot more consistent. PPS: i do also have a string representation of the lambda functions, if that helps I'm not sure if you need these to remain as lambdas, sure you can just pass it to a hybrid_method: class MyClass(Base): # @hybrid_method def run_compare(self, fn, *args): return fn(*args) query(MyClass).filter(MyClass.run_compare(some_lambda, some_other_object)) -- 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] alternate way to filter queries
On 26 Aug 2013, at 19:15, lars van gemerden l...@rational-it.com wrote: On Monday, August 26, 2013 5:23:07 PM UTC+2, Michael Bayer wrote: On Aug 26, 2013, at 11:14 AM, lars van gemerden la...@rational-it.com wrote: Hi all, This might be a bit of a stretch but here it goes: Say that i have a lambda function that takes a mapped object and teturns whether it is valid; e.g: lambda person: person.age 17 or person.length 1.75 is it possible to use this method to perform an sqla query on the database? Perhaps by using hybrid_method? Cheers, Lars PS: this might seem strange question, but it would save me a lot of work and/or would make my internal and user interfaces a lot more consistent. PPS: i do also have a string representation of the lambda functions, if that helps I'm not sure if you need these to remain as lambdas, sure you can just pass it to a hybrid_method: class MyClass(Base): # @hybrid_method def run_compare(self, fn, *args): return fn(*args) query(MyClass).filter(MyClass.run_compare(some_lambda, some_other_object)) Hi Michael, So just to be sure, if i understand correctly and i have: func = lambda person: person.age 17 or person.length 1.75 I can do: class Person(Base): # @hybrid_method def run_filter(self, fn): return fn(self) session.query(MyClass).filter(MyClass.run_compare(func)) to get all objects of class Person where obj.age17 or obj.length1.75 Is that without loading all records and filtering afterwards?? That's pretty impressive i think (and really helpful to me personally) Cheers, Lars As long as your function returns something meaningful when called with the class (Person) rather than an instance, it should be fine. Unfortunately I'm not sure your example will work, because expr or expr isn't something that SQLAlchemy can convert into an SQL statement. If you were able to use the bitwise or operator | instead, that would do the right thing. See the contains and intersects methods in the first example on http://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/hybrid.html. Hope that helps, Simon -- 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] alternate way to filter queries
oh , the or won't work as a hybrid, you either need to use the binary op | or otherwise run through some filter that will give you expression vs. local behavior. On Aug 26, 2013, at 2:15 PM, lars van gemerden l...@rational-it.com wrote: Hi Michael, So just to be sure, if i understand correctly and i have: func = lambda person: person.age 17 or person.length 1.75 I can do: class Person(Base): # @hybrid_method def run_filter(self, fn): return fn(self) session.query(MyClass).filter(MyClass.run_compare(func)) to get all objects of class Person where obj.age17 or obj.length1.75 Is that without loading all records and filtering afterwards?? That's pretty impressive i think (and really helpful to me personally) Cheers, Lars On Monday, August 26, 2013 5:23:07 PM UTC+2, Michael Bayer wrote: On Aug 26, 2013, at 11:14 AM, lars van gemerden la...@rational-it.com wrote: Hi all, This might be a bit of a stretch but here it goes: Say that i have a lambda function that takes a mapped object and teturns whether it is valid; e.g: lambda person: person.age 17 or person.length 1.75 is it possible to use this method to perform an sqla query on the database? Perhaps by using hybrid_method? Cheers, Lars PS: this might seem strange question, but it would save me a lot of work and/or would make my internal and user interfaces a lot more consistent. PPS: i do also have a string representation of the lambda functions, if that helps I'm not sure if you need these to remain as lambdas, sure you can just pass it to a hybrid_method: class MyClass(Base): # @hybrid_method def run_compare(self, fn, *args): return fn(*args) query(MyClass).filter(MyClass.run_compare(some_lambda, some_other_object)) -- 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] alternate way to filter queries
Hmm, too bad. I do have the lambda methods in string form so i'll probably have to write a parser and construct the query with unions and intersects (or filter(A.b 1, A.c0) like calls instead of intersects). No how did writing a parser tree go |-)? CL On Monday, August 26, 2013 8:27:16 PM UTC+2, Simon King wrote: On 26 Aug 2013, at 19:15, lars van gemerden la...@rational-it.comjavascript: wrote: On Monday, August 26, 2013 5:23:07 PM UTC+2, Michael Bayer wrote: On Aug 26, 2013, at 11:14 AM, lars van gemerden la...@rational-it.com wrote: Hi all, This might be a bit of a stretch but here it goes: Say that i have a lambda function that takes a mapped object and teturns whether it is valid; e.g: lambda person: person.age 17 or person.length 1.75 is it possible to use this method to perform an sqla query on the database? Perhaps by using hybrid_method? Cheers, Lars PS: this might seem strange question, but it would save me a lot of work and/or would make my internal and user interfaces a lot more consistent. PPS: i do also have a string representation of the lambda functions, if that helps I'm not sure if you need these to remain as lambdas, sure you can just pass it to a hybrid_method: class MyClass(Base): # @hybrid_method def run_compare(self, fn, *args): return fn(*args) query(MyClass).filter(MyClass.run_compare(some_lambda, some_other_object)) Hi Michael, So just to be sure, if i understand correctly and i have: func = lambda person: person.age 17 or person.length 1.75 I can do: class Person(Base): # @hybrid_method def run_filter(self, fn): return fn(self) session.query(MyClass).filter(MyClass.run_compare(func)) to get all objects of class Person where obj.age17 or obj.length1.75 Is that without loading all records and filtering afterwards?? That's pretty impressive i think (and really helpful to me personally) Cheers, Lars As long as your function returns something meaningful when called with the class (Person) rather than an instance, it should be fine. Unfortunately I'm not sure your example will work, because expr or expr isn't something that SQLAlchemy can convert into an SQL statement. If you were able to use the bitwise or operator | instead, that would do the right thing. See the contains and intersects methods in the first example on http://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/hybrid.html. Hope that helps, Simon -- 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 create a one-to-many relationship with a default one-to-one property for I18N
Hey there, I have already posted this on stackoverflowhttp://stackoverflow.com/questions/18304212/how-do-i-create-a-one-to-many-relationship-with-a-default-one-to-one-property-fobut not recieved an answer yet so I thought I might try here. To quote from my original question: Suppose we have these classes: class Item(Base): id = Column(Integer, primary_key=True) data = Column(String) i18ns = relationship(ItemI18n, backref=item) class ItemI18n(Base): lang_short = Column(String, primary_key=True) item_id = Column(Integer, ForeignKey('item.id'), primary_key=True) name = Column(String) [on pastebin http://pastebin.com/LQAMVy0Y] The idea here is to have this item's name in multiple languages, for example in English and German. This works fine so far, one can easily work with that. However, most times, I am not interested in all (i.e. both) names but only the users locale. For example, if the user is English and wants to have the name in his language, I see two options: # Use it as a list item = session.query(Item).first() print item.data, [i18n.name for i18n in item.i18ns if i18n.lang_short == en][0] # Get the name separately item, name = session.query(Item, ItemI18N.name).join(ItemI18N).filter(ItemI18N.lang_short == en).first() print item.data, name [on pastebin http://pastebin.com/VfuHBd86] The first one filters the list, the second one queries the language separately. The second is the more efficient way as it only pulls the data really needed. However, there is a drawback: I now have to carry around two variables: `item` and `name`. If I were to extend my `ItemI18N` for example, add a `description` property, then I would query for `ItemI18N` and carry those around. But business logic is different: I would expect to have an `Item` with a `name` and `description` attribute, so that I would do something like this: item = session.query(Item).first() print item.data, item.name So that's where I want to go: Pull all those attributes from `Item18N` directly into `Item`. And of course, I would have to specify the language anywhere. However, I cannot find any recipes for this since I don't even know what to search for. Can SQLAlchemy do such a thing? I also created a complete example http://pastebin.com/Ea1Bqzcw for everything I described (except of course the part I don't know how to realize). *Edit*: I have played around a bit more to see whether I can come up with a better solution and so far, I have found one way that works. I initially tried to realize it with `Query.get` but this doesn't work beyond my simple example, because reality is different. To explain, I have to extend my initial model by adding a `Language` table and turn `ItemI18N` into a many-to-many relationship with the primary key being `(lang_id, item_id)`: class ItemI18N(Base): lang_id = Column(Integer, ForeignKey('language.id'), primary_key=True) item_id = Column(Integer, ForeignKey('item.id'), primary_key=True) name = Column(String) language = relationship(Language, lazy=joined) class Language(Base): id = Column(Integer, primary_key=True) short = Column(String) Now to get my correct locale I simply turn all loadings into joined loadings by applying `lazy=joined` to the complete path. This will inevitable pull in all languages thus returning more data than I need. My approach is then completely independent of SQLAlchemy: class Item(Base): ... i18ns = relationship(ItemI18N, backref=item, cascade=all, delete-orphan, lazy=joined) def name(self, locale): for i18n in self.i18ns: if i18n.language.short == locale: return i18n.name But this is not a pretty solution, both because of the overhead of retrieving *all* I18N data from the database and then fitering that result back to *one* thus making it completely irrelevant that I pulled all in the first place (since the locale will stay the same the whole time). My new full example http://pastebin.com/iSTkESjg shows how only one query is executed and gives my transparent access - but with an ugly overhead I would like to avoid. The example also contains some playing around with transformationshttp://docs.sqlalchemy.org/en/rel_0_8/orm/extensions/hybrid.html#building-transformersI have done. This could point to a solution from that direction, but I wasn't happy with this either because it required me to pass in the `with_transformation` part every time. I'd like it much better if this would automatically be applied when `Item` is queried. But I have found no event or other for this. So now I have multiple solution attempts that all lack the ease of direct access compared to the business logic described above. I hope someone is able to
Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 ?
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 create a one-to-many relationship with a default one-to-one property for I18N
On Aug 26, 2013, at 3:43 PM, Florian Rüchel florian.ruec...@gmail.com wrote: Hey there, I have already posted this on stackoverflow but not recieved an answer yet so I thought I might try here. To quote from my original question: I've seen it, and the issue is that the question is difficult to parse. Suppose we have these classes: class Item(Base): id = Column(Integer, primary_key=True) data = Column(String) i18ns = relationship(ItemI18n, backref=item) class ItemI18n(Base): lang_short = Column(String, primary_key=True) item_id = Column(Integer, ForeignKey('item.id'), primary_key=True) name = Column(String) [on pastebin] The idea here is to have this item's name in multiple languages, for example in English and German. This works fine so far, one can easily work with that. However, most times, I am not interested in all (i.e. both) names but only the users locale. For example, if the user is English and wants to have the name in his language, I see two options: # Use it as a list item = session.query(Item).first() print item.data, [i18n.name for i18n in item.i18ns if i18n.lang_short == en][0] # Get the name separately item, name = session.query(Item, ItemI18N.name).join(ItemI18N).filter(ItemI18N.lang_short == en).first() print item.data, name Based on detail further down, I know what you want, but reading this was confusing. You mean item should offer its .name attribute in multiple languages, right? How would that be possible without using a method? otherwise how are you instructing the Item object as to what language you'd like? But business logic is different: I would expect to have an `Item` with a `name` and `description` attribute, so that I would do something like this: item = session.query(Item).first() print item.data, item.name This doesn't make any sense - where is description above? what does it do? So that's where I want to go: Pull all those attributes from `Item18N` directly into `Item`. how are you specifying which Item18N you want? pulling attributes is very easy and there are several approaches but only if you have the two objects to start with. And of course, I would have to specify the language anywhere. where's anywhere? def name(self, locale): OK here I see we finally have a name function with a locale, great ! But this is not a pretty solution, both because of the overhead of retrieving all I18N data from the database and then fitering that result back to one thus making it completely irrelevant that I pulled all in the first place Why do you need to retrieve all of the data? why not just retrieve the one you want? def name(self, locale): return object_session(self).query(ItemI18N.name).with_parent(self).filter(ItemI18N.locale == locale).scalar() with_parent is one of the helper operators mentioned in the tutorial: http://docs.sqlalchemy.org/en/rel_0_8/orm/tutorial.html?highlight=with_parent#common-relationship-operators if you didn't know about with_parent, this works too: def name(self, locale): return object_session(self).query(ItemI18N.name).filter(self.id == ItemI18N.item_id).filter(ItemI18N.locale == locale).scalar() there are also ways to turn this into a relationship() and use eager loading if that helps, slightly less simple. signature.asc Description: Message signed with OpenPGP using GPGMail
Re: [sqlalchemy] How to define metaclass for a class that extends from sqlalchemy declarative base ?
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