Re: [sqlalchemy] stucco_evolution 0.4 released
On Apr 20, 2012, at 6:52 PM, Jeff Dairiki wrote: > On Fri, Apr 20, 2012 at 03:44:55PM -0400, Michael Bayer wrote: >> >> The one thing that's needed as far as Alembic is concerned is the >> ability to control the name of the actual "migration" table per >> environment, this is a short feature add that's been sitting as an >> enhancement request for some time now. > > Since you mention it, I posted patches to > > > https://bitbucket.org/zzzeek/alembic/issue/34/make-version-table-name-configurable > > awhile ago and was awaiting feedback on them (until I forgot about them.) > The patches in addition to supporting a configurable version table name > also support two-column version tables which can be shared between Alembic > environments. > > (If you want to veto the two-column version table idea, I can whittle > it down to just the configurable-version-table-name part pretty easily.) I really have to get used to bitbucket and the need to press the "follow" button on these issues, since I was totally unaware of this ! looking now (and checking other issues for missed activity) > > Cheers, > Jeff > > -- > 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] stucco_evolution 0.4 released
On Fri, Apr 20, 2012 at 03:44:55PM -0400, Michael Bayer wrote: > > The one thing that's needed as far as Alembic is concerned is the > ability to control the name of the actual "migration" table per > environment, this is a short feature add that's been sitting as an > enhancement request for some time now. Since you mention it, I posted patches to https://bitbucket.org/zzzeek/alembic/issue/34/make-version-table-name-configurable awhile ago and was awaiting feedback on them (until I forgot about them.) The patches in addition to supporting a configurable version table name also support two-column version tables which can be shared between Alembic environments. (If you want to veto the two-column version table idea, I can whittle it down to just the configurable-version-table-name part pretty easily.) Cheers, Jeff -- 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: associationproxy for one-to-many
On Fri, Apr 20, 2012 at 9:28 PM, Michael Bayer wrote: > > On Apr 20, 2012, at 8:45 AM, Eric Lemoine wrote: > >> On Mon, Apr 16, 2012 at 10:49 PM, Eric Lemoine >> wrote: >>> Hi >>> >>> I'd like to use an associationproxy for a simple many-to-one relationship: >>> >>> class Child(Base): >>> __tablename__ = 'child' >>> id = Column(Integer, primary_key=True) >>> name = Column(Unicode) >>> >>> class Parent(Base): >>> __tablename__ = 'parent' >>> id = Column(Integer, primary_key=True) >>> child_id = Column(Integer, ForeignKey('child.id') >>> child_ = relationship(Child) >>> child = association_proxy('child_', 'name', creator=) >>> >>> Now 'child' is a read-only, dictionary-like table. I never want to insert >>> new rows in this table. >>> >>> So I actually pass the following "creator" to the association_proxy >>> constructor: >>> >>> def creator(name): >>> return Session.query(Child).filter_by(name=name).first() > >>> >>> That does the job for "create". But I cannot find a solution for "update". >>> On update I'd like to replace the current Child object in the Parent object >>> by a new Child object read from the 'child' table. >>> >>> Using a specific setter (in a getset_factory) does not work for me, as the >>> setter receives the Child object (and the value), not the Parent object – >>> I'd need a ref to the Parent object to be able to change its Child object in >>> child_. >>> >>> Maybe I'm doing it all wrong and using an associationproxy is not the way to >>> go for that case. > > the associationproxy is good for collections but in this case I'm not sure > what you're getting versus a regular @property or @hybrid_property. Yeah I was wondering too. And I actually did not know about the existence of hybrid_property. > > I will note that I think I do a use case a little bit similar to this, where > Parent.children is a dictionary keyed on name. But instead of sticking > Session.query() into creator, I use a recipe similar to the unique object > recipe: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject . This is also very good to know (and study). > > If the associationproxy is doing it's job, modifying "Parent.child", as a > string, should be updating Parent._child.name with the new value. If you > wanted to replace that with "just swap this other Child in", you could do > that in a before_flush() event, not unlike the insert versions recipe: > http://www.sqlalchemy.org/trac/wiki/UsageRecipes/VersionedRows > > but just sticking with @property or hybrid might be more straightforward > here, if it works. Yeah. Thanks a lot Mike! This gives me interesting paths to research. -- Eric Lemoine Camptocamp France SAS Savoie Technolac, BP 352 73377 Le Bourget du Lac, Cedex Tel : 00 33 4 79 44 44 96 Mail : eric.lemo...@camptocamp.com http://www.camptocamp.com -- 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] stucco_evolution 0.4 released
On Apr 20, 2012, at 4:52 AM, Wichert Akkerman wrote: > > That suggests that every package would have its own migration tool, which is > not very practical from a sysadmin point of view. I am an upgrading an > application I want to be able to run all necessary migrations for all > components of an application in one run. I do not want to be required to > figure out which packages an application was running and then migrate them > all separately. So I definitely see a need for an upgrade framework that can > deal with multiple packages. in my view every package which deals with it's own schema objects would at least have to maintain it's own migration files - not it's own migration "tool", but assuming an Alembic setup, each would have at least a rudimentary Alembic environment and individual migration files.You could then run each migration environment individually, or write a short coordination script within the main application that calls upon all of them. Assuming the packages either have no schema dependencies on each other, or dependencies without cycles, the correct "order" of which set of scripts to be run could just be hardcoded within the main application. i think when one writes an application M that makes use of libraries A, B, and C, it's not unreasonable that M would have to include some top-level configuration for A, B, and C, that is, adding each one to a list of packages in which to locate an alembic environment and run upgrades. Or there would be some other usage contract between A, B, C and M that allows for publishing of "migration" handles. What I don't see is that application M has within it migration scripts specific to A, B and C. A, B and C should maintain the knowledge of their own schemas and how they need to be upgraded for new versions of A, B and C I would think. The one thing that's needed as far as Alembic is concerned is the ability to control the name of the actual "migration" table per environment, this is a short feature add that's been sitting as an enhancement request for some time now. -- 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] join + joined inheritance
On Apr 20, 2012, at 9:32 AM, Julien Cigar wrote: > Hello, > > I'm using joined load inheritance in one of my project, and I have the > following query: > > q = Content.query.outerjoin((File, File.content_id == Content.id), File.mime, > Mime.major) > > SQLAlchemy generates a subquery for the outer join. > Any idea how to ask SQLAlchemy to generate a shorter FROM clause (no > subquery) ? > > This is what I get: > > FROM content LEFT OUTER JOIN (SELECT content.id AS content_id, content.added > AS content_added, content.updated AS content_updated, content.title AS > content_title, content.description AS content_description, content.effective > AS content_effective, content.expiration AS content_expiration, > content.exclude_nav AS content_exclude_nav, content.weight AS content_weight, > content.customized AS content_customized, content.content_type_id AS > content_content_type_id, content.icon_content_id AS content_icon_content_id, > content.container_id AS content_container_id, content.owner_id AS > content_owner_id, content.polymorphic_loading AS content_polymorphic_loading, > content.state_id AS content_state_id, data.content_id AS data_content_id, > data.mime_id AS data_mime_id, data.original_name AS data_original_name, > data.file_size AS data_file_size >FROM content JOIN data ON content.id = data.content_id) AS anon_1 ON > anon_1.data_content_id = content.id LEFT OUTER JOIN mime ON mime.id = > anon_1.data_mime_id LEFT OUTER JOIN mime_major ON mime_major.id = > mime.major_id > > This is what I want: > > FROM content LEFT OUTER JOIN data ON content.id = data.content_id LEFT OUTER > JOIN mime ON mime.id = anon_1.data_mime_id LEFT OUTER JOIN mime_major ON > mime_major.id = mime.major_id > > My mappers looks like: > > orm.mapper(Content, table['content'], > polymorphic_on = table['content'].c.content_type_id, > ...) > > orm.mapper(File, table['data'], inherits = Content, > polymorphic_identity = _get_type_id('file'), > ...) right this is the behavior of when you join to a joined inh structure. It represents essentially "A JOIN B", and not every database backend can seamlessly handle the idea of "C JOIN (A JOIN B)", though most can these days except for SQLite. There's some other nasty scoping problems on the SQLA expression side which come into play, however, and changing the mechanics of query.join()/outerjoin() to try to "optimize" this is not something likely to ever happen, as far as I can see (I've looked into seeing how it could be done). In particular here, File is already a composite of Content, so joining from Content-> File is pretty awkward. in this particular case, you can probably get what you want just by loading Content with the "with_polymorphic" option that will outer join to the related "file" table: query(Content).with_polymorphic([File]).outerjoin(File.mime, Mime.major) Otherwise, if you want to create a join among the components of a joined inheritance structure while maintaining explicit control over those components, you use the Table objects directly, that is File.__table__, and such. There's a detailed description of this at http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#basic-control-of-which-tables-are-queried and http://docs.sqlalchemy.org/en/latest/orm/inheritance.html#advanced-control-of-which-tables-are-queried . -- 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: automating inheritance
On Apr 20, 2012, at 8:51 AM, lars van gemerden wrote: > Ok, thank you, that helps, but now i cannot inherit from Engineer, as in: > > class BaseMixin(object): > > discriminator = Column(String(50)) > > @declared_attr > def __tablename__(cls): > return cls.__name__ > @declared_attr > def id(cls): > return Column(Integer, primary_key = True) > @declared_attr > def __mapper_args__(cls): > if not has_inherited_table(cls): > return {'polymorphic_on': 'discriminator'} > else: > return {'polymorphic_identity': cls.__name__} > > > class InheritMixin(BaseMixin): > @declared_attr > def id(cls): > super_id = super(InheritMixin, cls).id > return Column(Integer, ForeignKey(super_id), primary_key = True) > > class Person(BaseMixin, Base): > name = Column(String(50)) > > class Engineer(InheritMixin, Person): > job = Column(String(50)) > > class MasterEngineer(InheritMixin, Engineer): > specialty = Column(String(50)) > > Gives an MRO() error and if i would reverse the baseclasses (like class > Engineer(Person, InheritMixin): ... ), the inheriting classes pick up the > wrong id. > > Do you see any solution for this? yeah I suppose if you're building out joined inheritance more than one level then this becomes awkward. I never use joined inh more than one level because it has too much of an impact on queries. the metaclass as you mention is always the last resort when the various declarative trickery reaches its limit. I'm not thrilled about the metaclass approach because it quickly gets confusing and shouldn't be necessary. though in this case without some extra mechanism on declarative, such as a __pre_declare__() method of some kind, it might be the only approach. -- 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: associationproxy for one-to-many
On Apr 20, 2012, at 8:45 AM, Eric Lemoine wrote: > On Mon, Apr 16, 2012 at 10:49 PM, Eric Lemoine > wrote: >> Hi >> >> I'd like to use an associationproxy for a simple many-to-one relationship: >> >> class Child(Base): >> __tablename__ = 'child' >> id = Column(Integer, primary_key=True) >> name = Column(Unicode) >> >> class Parent(Base): >> __tablename__ = 'parent' >> id = Column(Integer, primary_key=True) >> child_id = Column(Integer, ForeignKey('child.id') >> child_ = relationship(Child) >> child = association_proxy('child_', 'name', creator=) >> >> Now 'child' is a read-only, dictionary-like table. I never want to insert >> new rows in this table. >> >> So I actually pass the following "creator" to the association_proxy >> constructor: >> >> def creator(name): >> return Session.query(Child).filter_by(name=name).first() >> >> That does the job for "create". But I cannot find a solution for "update". >> On update I'd like to replace the current Child object in the Parent object >> by a new Child object read from the 'child' table. >> >> Using a specific setter (in a getset_factory) does not work for me, as the >> setter receives the Child object (and the value), not the Parent object – >> I'd need a ref to the Parent object to be able to change its Child object in >> child_. >> >> Maybe I'm doing it all wrong and using an associationproxy is not the way to >> go for that case. the associationproxy is good for collections but in this case I'm not sure what you're getting versus a regular @property or @hybrid_property. I will note that I think I do a use case a little bit similar to this, where Parent.children is a dictionary keyed on name. But instead of sticking Session.query() into creator, I use a recipe similar to the unique object recipe: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/UniqueObject . If the associationproxy is doing it's job, modifying "Parent.child", as a string, should be updating Parent._child.name with the new value. If you wanted to replace that with "just swap this other Child in", you could do that in a before_flush() event, not unlike the insert versions recipe: http://www.sqlalchemy.org/trac/wiki/UsageRecipes/VersionedRows but just sticking with @property or hybrid might be more straightforward here, if it works. -- 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.
multi-package schemas (was Re: [sqlalchemy] stucco_evolution 0.4 released)
On 19/04/2012 18:43, Michael Bayer wrote: but with the possibility of dependencies between those tables. If I understand correctly, if we were dealing with sets of tables that didn't have any dependency, you wouldn't need a distributed migration tool, each package would handle migrations for its own set of tables independently, is that right ? This is what I came up with for mortar_rdb: each package defined a "source" of tables and each application collected the sources it was using into a "config". Each "source" has its own schema. I haven't hit a situation where I needed the topological sort yet, I suspect if I did I'd just punt and make the owner of the config (ie: the application) specify the upgrade order manually... I think what I need to see here are, what exactly are these packages, Authentication, authorization and "membership" are the obvious ones; all three have several interchangeable solutions and I can certainly conceive packages for each interoperating with a few select foreign keys, username being the most obvious... Admittedly, I haven't hit this in the "real world" yet. I'm very keen to move mortar_rdb onto Alebic, and will be doing so as soon as I hit the need in the real world... 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.
[sqlalchemy] join + joined inheritance
Hello, I'm using joined load inheritance in one of my project, and I have the following query: q = Content.query.outerjoin((File, File.content_id == Content.id), File.mime, Mime.major) SQLAlchemy generates a subquery for the outer join. Any idea how to ask SQLAlchemy to generate a shorter FROM clause (no subquery) ? This is what I get: FROM content LEFT OUTER JOIN (SELECT content.id AS content_id, content.added AS content_added, content.updated AS content_updated, content.title AS content_title, content.description AS content_description, content.effective AS content_effective, content.expiration AS content_expiration, content.exclude_nav AS content_exclude_nav, content.weight AS content_weight, content.customized AS content_customized, content.content_type_id AS content_content_type_id, content.icon_content_id AS content_icon_content_id, content.container_id AS content_container_id, content.owner_id AS content_owner_id, content.polymorphic_loading AS content_polymorphic_loading, content.state_id AS content_state_id, data.content_id AS data_content_id, data.mime_id AS data_mime_id, data.original_name AS data_original_name, data.file_size AS data_file_size FROM content JOIN data ON content.id = data.content_id) AS anon_1 ON anon_1.data_content_id = content.id LEFT OUTER JOIN mime ON mime.id = anon_1.data_mime_id LEFT OUTER JOIN mime_major ON mime_major.id = mime.major_id This is what I want: FROM content LEFT OUTER JOIN data ON content.id = data.content_id LEFT OUTER JOIN mime ON mime.id = anon_1.data_mime_id LEFT OUTER JOIN mime_major ON mime_major.id = mime.major_id My mappers looks like: orm.mapper(Content, table['content'], polymorphic_on = table['content'].c.content_type_id, ...) orm.mapper(File, table['data'], inherits = Content, polymorphic_identity = _get_type_id('file'), ...) Thanks!, Julien -- No trees were killed in the creation of this message. However, many electrons were terribly inconvenienced. -- 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: automating inheritance
Hi Mike, How about this approach with a custom metaclass; so far it works and seems the cleanest to me: from sqlalchemy import * from sqlalchemy.orm.session import sessionmaker from sqlalchemy.ext.declarative import declarative_base, has_inherited_table, DeclarativeMeta engine = create_engine('sqlite:///:memory:', echo=False) class InheritMeta(DeclarativeMeta): def __init__(cls, name, bases, clsdict): cls.__tablename__ = cls.__name__ if not has_inherited_table(cls): cls.id = Column(Integer, primary_key = True) cls.discriminator = Column(String(50)) cls.__mapper_args__ = {'polymorphic_on': 'discriminator'} else: cls.id = Column(Integer, ForeignKey(bases[0].id), primary_key = True) cls.__mapper_args__ = {'polymorphic_identity': cls.__name__} super(InheritMeta, cls).__init__(name, bases, clsdict) InheritableBase = declarative_base(bind = engine, metaclass = InheritMeta) class Person(InheritableBase): name = Column(String(50)) class Engineer(Person): job = Column(String(50)) class MasterEngineer(Engineer): specialty = Column(String(50)) if __name__ == '__main__': InheritableBase.metadata.create_all(engine) session = sessionmaker(bind=engine)() a = Person(name = 'ann') b = Engineer(name = 'bob', job = 'car repair') c = MasterEngineer(name = 'carl', job = 'car repair', specialty = 'tires') session.add_all([a, b, c]) session.commit() people = session.query(Person).all() print people Do you see any drawbacks, gotchas for later on? Regards, Lars On Friday, April 20, 2012 12:41:28 PM UTC+2, Michael Bayer wrote: > > > On Apr 20, 2012, at 4:59 AM, lars van gemerden wrote: > > > this is the testcase: > > > > > > What am i missing? > > > the issue here is one of Python inheritance mechanics. Declarative calls > upon @declared_attr in terms of the class, that is, we look through the > class to find each @declared_attr, but when we find one, we invoke it by > just calling it as a method, that is, getattr(cls, name). This works for > things like __mapper_args__ which remain as callable methods on classes > like Person, Engineer. But "id", when that is declared on Person is > immediately replaced with a mapping. By the time you get to Engineer, the > id() method is gone. > > So for inheriting cases you need to build a mixin that is applied to every > subclass. This makes sense because a mixin with a column on it implies > that the column is being associated only with that immediate class - if you > wanted a subclass to act as single table inheritance, you'd omit this > class. In this case you want the same column on all subclasses.So you > can do it like this (note also using declarative.has_inherited_table > helper): > > class InheritMixin(object): > >@declared_attr >def __tablename__(cls): >return cls.__name__ > >@declared_attr >def id(cls): >return Column(Integer, primary_key = True) > >@declared_attr >def __mapper_args__(cls): >if not has_inherited_table(cls): >return {'polymorphic_on': 'discriminator'} >else: >return {'polymorphic_identity': cls.__name__} > > class Inherits(InheritMixin): > @declared_attr > def id(cls): > super_id = super(Inherits, cls).id > return Column(Integer, ForeignKey(super_id),primary_key = True) > > class Person(InheritMixin, Base): >discriminator = Column(String(50)) >name = Column(String(50)) > > class Engineer(Inherits, Person): >job = Column(String(50)) > > > this should be in the docs so I've added ticket #2471 to handle this. > > > > > Cheers, Lars > > > > > > On Apr 19, 4:13 pm, Michael Bayer wrote: > >> On Apr 19, 2012, at 6:23 AM, lars van gemerden wrote: > >> > >> > >> > >> > >> > >> > >> > >> > >> > >>> I am trying to my my joined inheritance code clearer, for the dynamic > >>> generation of sa classes and tried to do something like this: > >> > >>> class InheritMixin(object): > >> > >>>@declared_attr > >>>def __tablename__(cls): > >>>return cls.__name__ > >>>@declared_attr > >>>def id(cls): > >>>if cls.__name__ == 'Object': > >>>return Column(Integer, primary_key = True) > >>>else: > >>>print 'in id: ', cls.__name__, cls.__bases__[0].__name__ > >>>return Column(Integer, > >>> ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True) > >>>@declared_attr > >>>def __mapper_args__(cls): > >>>if cls.__name__ == 'Object': > >>>return {'polymorphic_on': 'discriminator'} > >>>else: > >>>print 'in mapper_args: ', cls.__name__, > >>> cls.__bases__[0].__name__ > >>>return {'polymorphic_identity': cls.__name__, > >>>'inherit_condition': (cls.id == > >>> cls.__bases__[0].id)} > >> > >>> Object = type
Re: [sqlalchemy] Re: automating inheritance
Ok, thank you, that helps, but now i cannot inherit from Engineer, as in: class BaseMixin(object): discriminator = Column(String(50)) @declared_attr def __tablename__(cls): return cls.__name__ @declared_attr def id(cls): return Column(Integer, primary_key = True) @declared_attr def __mapper_args__(cls): if not has_inherited_table(cls): return {'polymorphic_on': 'discriminator'} else: return {'polymorphic_identity': cls.__name__} class InheritMixin(BaseMixin): @declared_attr def id(cls): super_id = super(InheritMixin, cls).id return Column(Integer, ForeignKey(super_id), primary_key = True) class Person(BaseMixin, Base): name = Column(String(50)) class Engineer(InheritMixin, Person): job = Column(String(50)) class MasterEngineer(InheritMixin, Engineer): specialty = Column(String(50)) Gives an MRO() error and if i would reverse the baseclasses (like class Engineer(Person, InheritMixin): ... ), the inheriting classes pick up the wrong id. Do you see any solution for this? BTW: could i just move @declared_attr def __mapper_args__(cls): return {'polymorphic_identity': cls.__name__} to InheritMixin instead of doing the 'has_inherited_table' if-statement in BaseMixin? Cheers, Lars On Friday, April 20, 2012 12:41:28 PM UTC+2, Michael Bayer wrote: > > > On Apr 20, 2012, at 4:59 AM, lars van gemerden wrote: > > > this is the testcase: > > > > > > What am i missing? > > > the issue here is one of Python inheritance mechanics. Declarative calls > upon @declared_attr in terms of the class, that is, we look through the > class to find each @declared_attr, but when we find one, we invoke it by > just calling it as a method, that is, getattr(cls, name). This works for > things like __mapper_args__ which remain as callable methods on classes > like Person, Engineer. But "id", when that is declared on Person is > immediately replaced with a mapping. By the time you get to Engineer, the > id() method is gone. > > So for inheriting cases you need to build a mixin that is applied to every > subclass. This makes sense because a mixin with a column on it implies > that the column is being associated only with that immediate class - if you > wanted a subclass to act as single table inheritance, you'd omit this > class. In this case you want the same column on all subclasses.So you > can do it like this (note also using declarative.has_inherited_table > helper): > > class InheritMixin(object): > >@declared_attr >def __tablename__(cls): >return cls.__name__ > >@declared_attr >def id(cls): >return Column(Integer, primary_key = True) > >@declared_attr >def __mapper_args__(cls): >if not has_inherited_table(cls): >return {'polymorphic_on': 'discriminator'} >else: >return {'polymorphic_identity': cls.__name__} > > class Inherits(InheritMixin): > @declared_attr > def id(cls): > super_id = super(Inherits, cls).id > return Column(Integer, ForeignKey(super_id),primary_key = True) > > class Person(InheritMixin, Base): >discriminator = Column(String(50)) >name = Column(String(50)) > > class Engineer(Inherits, Person): >job = Column(String(50)) > > > this should be in the docs so I've added ticket #2471 to handle this. > > > > > Cheers, Lars > > > > > > On Apr 19, 4:13 pm, Michael Bayer wrote: > >> On Apr 19, 2012, at 6:23 AM, lars van gemerden wrote: > >> > >> > >> > >> > >> > >> > >> > >> > >> > >>> I am trying to my my joined inheritance code clearer, for the dynamic > >>> generation of sa classes and tried to do something like this: > >> > >>> class InheritMixin(object): > >> > >>>@declared_attr > >>>def __tablename__(cls): > >>>return cls.__name__ > >>>@declared_attr > >>>def id(cls): > >>>if cls.__name__ == 'Object': > >>>return Column(Integer, primary_key = True) > >>>else: > >>>print 'in id: ', cls.__name__, cls.__bases__[0].__name__ > >>>return Column(Integer, > >>> ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True) > >>>@declared_attr > >>>def __mapper_args__(cls): > >>>if cls.__name__ == 'Object': > >>>return {'polymorphic_on': 'discriminator'} > >>>else: > >>>print 'in mapper_args: ', cls.__name__, > >>> cls.__bases__[0].__name__ > >>>return {'polymorphic_identity': cls.__name__, > >>>'inherit_condition': (cls.id == > >>> cls.__bases__[0].id)} > >> > >>> Object = type('Object', (Base, InheritMixin), clsdict) > >> > >>> Where Object should be the (not necessarily direct) baseclass of all > >>> inheriting classes. However I get errors: "Mapper Mapper|person|person > >>> could not assemble any primary key columns for mapped table 'Join > >>> objec
[sqlalchemy] Re: associationproxy for one-to-many
On Mon, Apr 16, 2012 at 10:49 PM, Eric Lemoine wrote: > Hi > > I'd like to use an associationproxy for a simple many-to-one relationship: > > class Child(Base): > __tablename__ = 'child' > id = Column(Integer, primary_key=True) > name = Column(Unicode) > > class Parent(Base): > __tablename__ = 'parent' > id = Column(Integer, primary_key=True) > child_id = Column(Integer, ForeignKey('child.id') > child_ = relationship(Child) > child = association_proxy('child_', 'name', creator=) > > Now 'child' is a read-only, dictionary-like table. I never want to insert > new rows in this table. > > So I actually pass the following "creator" to the association_proxy > constructor: > > def creator(name): > return Session.query(Child).filter_by(name=name).first() > > That does the job for "create". But I cannot find a solution for "update". > On update I'd like to replace the current Child object in the Parent object > by a new Child object read from the 'child' table. > > Using a specific setter (in a getset_factory) does not work for me, as the > setter receives the Child object (and the value), not the Parent object – > I'd need a ref to the Parent object to be able to change its Child object in > child_. > > Maybe I'm doing it all wrong and using an associationproxy is not the way to > go for that case. > > Thanks for any suggestion. No comment for this? Thanks, -- Eric Lemoine Camptocamp France SAS Savoie Technolac, BP 352 73377 Le Bourget du Lac, Cedex Tel : 00 33 4 79 44 44 96 Mail : eric.lemo...@camptocamp.com http://www.camptocamp.com -- 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] startswith column operator - db specific
Michael, On 20/04/2012 12:21, Michael Bayer wrote: On Apr 20, 2012, at 4:51 AM, Werner wrote: On 20/04/2012 10:36, Werner wrote: I use Firebird SQL, and "like" has a pretty bad performance compared to "starting with", as the later uses an index if one is available. When using "someklass.somecolumn.startswith('value') SA uses "like", what would have to be done to use "starting with" instead for the Firebird dialect? Hhm, The performance issue should be solved with 2.1+, so did some more search and testing. SA generates something like this when using "startswith" - correct? select name from cepagesyn where NAME like 'merlot' || '%%'; If I run the above in IBExpert (the db tool I use to admin) it is very slow as the plan is "CEPAGESYN NATURAL" if I use: select name from cepagesyn where NAME like 'merlot%'; PLAN (CEPAGESYN INDEX (IX_CEPAGESYN_NAME)) So, could the FB dialect be tweaked to do the concatenation in Python instead of how it is done now? Werner As always thanks for your quick feed back. the concatenation in SQL is there to handle the case of the argument not being a literal string, i.e. another SQL expression like a column. There also might be some edges to it related to escape characters, not sure. To really handle this we'd have to adjust the mechanism of startswith, endswith, contains to move their evaluation out to the compiler, instead of hardwiring them to the concatenation. This is probably a good idea in any case though might be a bit destabilizing, might be better for 0.8.In the FB case it would render "STARTING WITH". Would be great if that makes it into 0.8. for the moment as a workaround I'd employ your own startswith() function, or use mycol.op('starting with')(value). That works great for the case I had a performance issue with. Thanks a lot Werner -- 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: Mixing a column declared with @declared_attr into a child class is not mapped in parent class when using STI
there's other edges too, like a custom Column subclass, and contents within the open-ended info dict, so __conflicts__ keeps this simple. I've added ticket 2472 for this. On Apr 19, 2012, at 4:31 PM, Amos wrote: > It would be great for declarative to resolve a conflict (perhaps with > a warning) if the column definitions are exactly the same - though I > can see this getting complicated with nested ForeignKey objects, etc. > That said, I really like the idea of exposing the conflict resolution > mechanism to the user. Perhaps, it could even be made simpler by > adding a kwarg to the Column definition: > > class MyMixin(object): >@declared_attr >def target_id(cls): >return Column(Integer, ForeignKey('target.id'), > replace_existing=True) > > On Apr 18, 7:11 am, Michael Bayer wrote: >> On Apr 17, 2012, at 8:23 PM, Amos wrote: >> >>> Thanks for the clarification. I did play around with __abstract__ but >>> like you said it doesn't work in the middle of the inheritance chain. >>> The main idea behind this approach is the DRY concept - define the >>> columns/relationships only once and use them interchangeably in any of >>> the derived STI models. This workaround sort of accomplishes that but >>> at the same time restricts you to a hierarchical model, whereas using >>> mixins is much more flexible. >> >> the issue with mixins here is that you essentially have two mixins saying >> something that conflicts, they both create a Column object with the same >> name. One could have a different "info" dict than the other, for example - >> it would be a surprise for declarative to just pick one, and discard the >> other. For declarative to compare them is also something I'd rather not >> get into as again things like the "info" dict and custom subclasses of >> Column couldn't necessarily be compared. >> >> But I thought of a possible way to give this capability to you, a new method >> __conflicts__, like this: >> >> class MyMixin(object): >> @declared_attr >> def target_id(cls): >> return Column(Integer, ForeignKey('target.id')) >> >> @classmethod >> def __conflicts__(cls, key, existing, new): >> if key == 'target_id': >> return existing >> else: >>return None >> >> so basically, instead of declarative raising "column x conflicts with >> existing" it will first call __conflicts__ on your class (which could be >> anywhere in the hierarchy), giving your code a chance to resolve. >> >> What I like about this is that declarative's behavioral contract doesn't >> change at all for anybody, it doesn't have to get into comparing or silent >> guessing, and the feature itself, which would be very rarely used as this is >> not a typical use case, would have a decent place for documenting under the >> "special methods" section of declarative and also be a very simple, two line >> feature. > > -- > 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] Re: automating inheritance
On Apr 20, 2012, at 4:59 AM, lars van gemerden wrote: > this is the testcase: > > > What am i missing? the issue here is one of Python inheritance mechanics. Declarative calls upon @declared_attr in terms of the class, that is, we look through the class to find each @declared_attr, but when we find one, we invoke it by just calling it as a method, that is, getattr(cls, name). This works for things like __mapper_args__ which remain as callable methods on classes like Person, Engineer. But "id", when that is declared on Person is immediately replaced with a mapping. By the time you get to Engineer, the id() method is gone. So for inheriting cases you need to build a mixin that is applied to every subclass. This makes sense because a mixin with a column on it implies that the column is being associated only with that immediate class - if you wanted a subclass to act as single table inheritance, you'd omit this class. In this case you want the same column on all subclasses.So you can do it like this (note also using declarative.has_inherited_table helper): class InheritMixin(object): @declared_attr def __tablename__(cls): return cls.__name__ @declared_attr def id(cls): return Column(Integer, primary_key = True) @declared_attr def __mapper_args__(cls): if not has_inherited_table(cls): return {'polymorphic_on': 'discriminator'} else: return {'polymorphic_identity': cls.__name__} class Inherits(InheritMixin): @declared_attr def id(cls): super_id = super(Inherits, cls).id return Column(Integer, ForeignKey(super_id),primary_key = True) class Person(InheritMixin, Base): discriminator = Column(String(50)) name = Column(String(50)) class Engineer(Inherits, Person): job = Column(String(50)) this should be in the docs so I've added ticket #2471 to handle this. > > Cheers, Lars > > > On Apr 19, 4:13 pm, Michael Bayer wrote: >> On Apr 19, 2012, at 6:23 AM, lars van gemerden wrote: >> >> >> >> >> >> >> >> >> >>> I am trying to my my joined inheritance code clearer, for the dynamic >>> generation of sa classes and tried to do something like this: >> >>> class InheritMixin(object): >> >>>@declared_attr >>>def __tablename__(cls): >>>return cls.__name__ >>>@declared_attr >>>def id(cls): >>>if cls.__name__ == 'Object': >>>return Column(Integer, primary_key = True) >>>else: >>>print 'in id: ', cls.__name__, cls.__bases__[0].__name__ >>>return Column(Integer, >>> ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True) >>>@declared_attr >>>def __mapper_args__(cls): >>>if cls.__name__ == 'Object': >>>return {'polymorphic_on': 'discriminator'} >>>else: >>>print 'in mapper_args: ', cls.__name__, >>> cls.__bases__[0].__name__ >>>return {'polymorphic_identity': cls.__name__, >>>'inherit_condition': (cls.id == >>> cls.__bases__[0].id)} >> >>> Object = type('Object', (Base, InheritMixin), clsdict) >> >>> Where Object should be the (not necessarily direct) baseclass of all >>> inheriting classes. However I get errors: "Mapper Mapper|person|person >>> could not assemble any primary key columns for mapped table 'Join >>> object on Object(65389120) and person(65428224)' " etc .. >> >> im not sure of the cause of that error, can you attach a full test case >> which illustrates this message being generated ? >> >> >> >>> I noticed that the method __mapper_args__(cls) is always called before >>> id(cls) (which is never called, probably due to the error. >> >> the __mapper_args__(cls) method here directly calls upon .id, so if you see >> .id() not being called it suggests some other form of .id is being used. >> >> Is it possible that Base or something else has a conflicting "id" attribute? >> >> >> >>> Also, is there a way to add the discriminator column to the mixin (if >>> i just directly add it to the declaration, this gave another maybe >>> related error)? >> >> maybe, let's start with the general idea of the mixin you're going to send >> me as a working script. > > -- > 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] startswith column operator - db specific
On Apr 20, 2012, at 4:51 AM, Werner wrote: > On 20/04/2012 10:36, Werner wrote: >> I use Firebird SQL, and "like" has a pretty bad performance compared to >> "starting with", as the later uses an index if one is available. >> >> When using "someklass.somecolumn.startswith('value') SA uses "like", what >> would have to be done to use "starting with" instead for the Firebird >> dialect? >> > Hhm, > > The performance issue should be solved with 2.1+, so did some more search and > testing. > > SA generates something like this when using "startswith" - correct? > > select name from cepagesyn where NAME like 'merlot' || '%%'; > > If I run the above in IBExpert (the db tool I use to admin) it is very slow > as the plan is "CEPAGESYN NATURAL" > > if I use: > > select name from cepagesyn where NAME like 'merlot%'; > > PLAN (CEPAGESYN INDEX (IX_CEPAGESYN_NAME)) > > So, could the FB dialect be tweaked to do the concatenation in Python instead > of how it is done now? > > Werner the concatenation in SQL is there to handle the case of the argument not being a literal string, i.e. another SQL expression like a column. There also might be some edges to it related to escape characters, not sure. To really handle this we'd have to adjust the mechanism of startswith, endswith, contains to move their evaluation out to the compiler, instead of hardwiring them to the concatenation. This is probably a good idea in any case though might be a bit destabilizing, might be better for 0.8.In the FB case it would render "STARTING WITH". for the moment as a workaround I'd employ your own startswith() function, or use mycol.op('starting with')(value). -- 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: automating inheritance
this is the testcase: from sqlalchemy import * from sqlalchemy.orm.session import sessionmaker from sqlalchemy.ext.declarative import declarative_base, declared_attr engine = create_engine('sqlite:///:memory:', echo=False) Base = declarative_base(bind = engine) Session = sessionmaker(bind = engine) def setup(engine): Base.metadata.create_all(engine) Session = sessionmaker(bind=engine) return Session() class InheritMixin(object): @declared_attr def __tablename__(cls): return cls.__name__ @declared_attr def id(cls): if Base in cls.__bases__: print 'base in id(cls): ', cls return Column(Integer, primary_key = True) else: print 'in id(cls): ', cls, cls.__bases__[0] return Column(Integer, ForeignKey(cls.__bases__[0].id), primary_key = True) @declared_attr def __mapper_args__(cls): if Base in cls.__bases__: print 'base in __mapper_args__(cls): ', cls return {'polymorphic_on': 'discriminator'} else: print 'in __mapper_args__(cls): ', cls, cls.__bases__[0], cls.id, (cls.id is cls.__bases__[0].id) return {'polymorphic_identity': cls.__name__} class Person(Base, InheritMixin): discriminator = Column(String(50)) name = Column(String(50)) class Engineer(Person): job = Column(String(50)) if __name__ == '__main__': session = setup(engine) a = Person(name = 'ann') b = Engineer(name = 'bob', job = 'car repair') session.add_all([a, b]) session.commit() people = session.query(Person).all() print people Note that i left out the 'inherit_condition', because without there is already a problem: base in id(cls): base in mapper_args(cls): in mapper_args(cls):Person.id True Traceback (most recent call last): File "D:\Documents\Code\Eclipse\workspace\process_data3\src \little_tests2.py", line 40, in class Engineer(Person): File "C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py", line 1336, in __init__ _as_declarative(cls, classname, cls.__dict__) File "C:\Python27\lib\site-packages\sqlalchemy\ext\declarative.py", line 1329, in _as_declarative **mapper_args) File "C:\Python27\lib\site-packages\sqlalchemy\orm\__init__.py", line 1116, in mapper return Mapper(class_, local_table, *args, **params) File "C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py", line 197, in __init__ self._configure_inheritance() File "C:\Python27\lib\site-packages\sqlalchemy\orm\mapper.py", line 473, in _configure_inheritance self.local_table) File "C:\Python27\lib\site-packages\sqlalchemy\sql\util.py", line 303, in join_condition "between '%s' and '%s'.%s" % (a.description, b.description, hint)) sqlalchemy.exc.ArgumentError: Can't find any foreign key relationships between 'Person' and 'Engineer'. What am i missing? Cheers, Lars On Apr 19, 4:13 pm, Michael Bayer wrote: > On Apr 19, 2012, at 6:23 AM, lars van gemerden wrote: > > > > > > > > > > > I am trying to my my joined inheritance code clearer, for the dynamic > > generation of sa classes and tried to do something like this: > > > class InheritMixin(object): > > > @declared_attr > > def __tablename__(cls): > > return cls.__name__ > > @declared_attr > > def id(cls): > > if cls.__name__ == 'Object': > > return Column(Integer, primary_key = True) > > else: > > print 'in id: ', cls.__name__, cls.__bases__[0].__name__ > > return Column(Integer, > > ForeignKey(cls.__bases__[0].__name__ + '.id'), primary_key = True) > > @declared_attr > > def __mapper_args__(cls): > > if cls.__name__ == 'Object': > > return {'polymorphic_on': 'discriminator'} > > else: > > print 'in mapper_args: ', cls.__name__, > > cls.__bases__[0].__name__ > > return {'polymorphic_identity': cls.__name__, > > 'inherit_condition': (cls.id == > > cls.__bases__[0].id)} > > > Object = type('Object', (Base, InheritMixin), clsdict) > > > Where Object should be the (not necessarily direct) baseclass of all > > inheriting classes. However I get errors: "Mapper Mapper|person|person > > could not assemble any primary key columns for mapped table 'Join > > object on Object(65389120) and person(65428224)' " etc .. > > im not sure of the cause of that error, can you attach a full test case which > illustrates this message being generated ? > > > > > I noticed that the method __mapper_args__(cls) is always called before > > id(cls) (which is never called, probably due to the error. > > the __mapper_args__(cls) method here directly calls upon .id, so if you see > .id() not being called it suggests some other form of .id is being used. > > Is it possible that Base or something else has a conflicting "id" attribute? > > > > > Also, is there a way to add the discriminator column to the mixin (if > > i just directly add it to the decla
Re: [sqlalchemy] stucco_evolution 0.4 released
On 04/19/2012 07:43 PM, Michael Bayer wrote: If you've seen my recent talks you saw that I'm a little skeptical of what you're terming "non-monolithic" databases.Let's say this means, a database with a set of tables maintained by entirely different packages, but with the possibility of dependencies between those tables.If I understand correctly, if we were dealing with sets of tables that didn't have any dependency, you wouldn't need a distributed migration tool, each package would handle migrations for its own set of tables independently, is that right ? That suggests that every package would have its own migration tool, which is not very practical from a sysadmin point of view. I am an upgrading an application I want to be able to run all necessary migrations for all components of an application in one run. I do not want to be required to figure out which packages an application was running and then migrate them all separately. So I definitely see a need for an upgrade framework that can deal with multiple packages. I think what I need to see here are, what exactly are these packages, outside of the Django community, that actually create their own tables yet encourage dependencies between those tables and your app's own tables ? I know people are working on them since I see people asking questions about those use cases, but what are they ? What's the openid and user/groups package you're thinking of here ? s4u.image is such an example: https://github.com/2style4you/s4u.image . That package implements an image store which supports on-demand scaling of images. Metadata is stored in a SQL database and commonly you add references to images to other tables. Every site we build uses s4u.image to manage image handling. This happens to be in-house developed by us, but for all intents and purposes it is a third-party package to our front-end developers. In the development world I've always lived in, we just don't have third party libraries that bring in their own sub-schemas. Up until now the thinking has been, if it's significant enough that it is part of your datamodel, it's part of what you should own yourself, though certainly drawing upon past recipes. I suspect a difference is that we are often building different sites that build on shared common functionality. Our main business is building sites that deal with online fashion, so everything we build has to deal with things like images and clothing articles. The code to handle those has been split out to separate packages (s4u.image is one of those) that define core datamodels and some logic, and our sites build on those. Sometimes we extend the base models, for example when for a particular site we need to track extra data for clothing, and sometimes we use the base models as-is and reference them directly via relationships and foreign keys. That results in an ecosystem of many different packages and sites that each have their own evolve in their own way and require their own migrations. When we upgrade a site our process is pretty simple: upgrade version pins for buildout, rerun buildout, run upgrade-script, tell mod_wsgi to reload. The upgrade-script walks through all migrations from all packages a site uses so we have a single interface for administrators to upgrade everything. The upgrade framework itself is extremely minimal (see https://github.com/2style4you/s4u.upgrade ), but works well enough for us. Note that we deviate from stucco_evolution in three important ways: we do not use versioning but require upgrade steps to test if an upgrade is necessary, our upgrade framework is not tied to SQLAlchemy but has a more generic requirements-system so you can use it for other things (we use it for filesystem changes and SOLR configuration as well for example), and it does not support dependencies. Personally I consider the first two to be desirable qualities for an upgrade framework. Dependencies are something that we will probably need to add at some point. 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.
Re: [sqlalchemy] startswith column operator - db specific
On 20/04/2012 10:36, Werner wrote: I use Firebird SQL, and "like" has a pretty bad performance compared to "starting with", as the later uses an index if one is available. When using "someklass.somecolumn.startswith('value') SA uses "like", what would have to be done to use "starting with" instead for the Firebird dialect? Hhm, The performance issue should be solved with 2.1+, so did some more search and testing. SA generates something like this when using "startswith" - correct? select name from cepagesyn where NAME like 'merlot' || '%%'; If I run the above in IBExpert (the db tool I use to admin) it is very slow as the plan is "CEPAGESYN NATURAL" if I use: select name from cepagesyn where NAME like 'merlot%'; PLAN (CEPAGESYN INDEX (IX_CEPAGESYN_NAME)) So, could the FB dialect be tweaked to do the concatenation in Python instead of how it is done now? Werner -- 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] startswith column operator - db specific
I use Firebird SQL, and "like" has a pretty bad performance compared to "starting with", as the later uses an index if one is available. When using "someklass.somecolumn.startswith('value') SA uses "like", what would have to be done to use "starting with" instead for the Firebird dialect? Werner -- 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.