Anyone? This has me dead in the water and nothing in the documentation has been helping.
- Ken On Mon, Jun 23, 2014 at 5:09 PM, Ken Lareau <klar...@tagged.com> wrote: > On Fri, Jun 20, 2014 at 3:46 PM, Ken Lareau <klar...@tagged.com> wrote: > >> On Fri, Jun 20, 2014 at 1:23 PM, Mike Bayer <mike...@zzzcomputing.com> >> wrote: >> >>> >>> On 6/20/14, 3:38 PM, Ken Lareau wrote: >>> >>> So in the ongoing improvement of one of our internal databases, we >>> created >>> a new table named 'environments' whose SQLA code looks something like >>> this: >>> >>> class Environment(Base): >>> __tablename__ = 'environments' >>> >>> id = Column(u'environmentID', INTEGER(), primary_key=True) >>> environment = Column(String(length=15), nullable=False, unique=True) >>> env = Column(String(length=12), nullable=False, unique=True) >>> domain = Column(String(length=32), nullable=False, unique=True) >>> prefix = Column(String(length=1), nullable=False) >>> >>> Two of our tables recently needed conversion to stop using their own >>> local >>> 'environment' column to using this table. The first part's been put >>> in place >>> (a new foreign key for 'environment_id'), but to prevent large swaths >>> of code >>> from needing changes, a thought of using a hybrid property might allow >>> the >>> change to be hidden (until the code using it had been rewritten at >>> least). >>> >>> My naive attempt was the following (just the relevant snippet): >>> >>> environment_obj = relationship('Environment') >>> >>> @hybrid_property >>> def environment(self): >>> return self.environment_obj.environment >>> >>> Unfortunately (and in hindsight for obvious reasons), this code >>> doesn't work, >>> >>> what does "doesn't work" mean here? This will work at the instance >>> level. At the query level, not so much, that's true, if you truly want no >>> code to change you'd need to implement an @expression here that's a little >>> inefficient, as it needs to do a correlated subq: >>> >>> >> Yes, the "doesn't work" was specifically related to an attempt to use it >> in >> a query, which of course failed miserably. :) >> >> >>> class HasEnv(Base): >>> __tablename__ = 'has_env' >>> >>> id = Column(INTEGER, primary_key=True) >>> environment_id = Column(ForeignKey('environments.environmentID')) >>> >>> >>> environment_obj = relationship('Environment') >>> >>> @hybrid_property >>> def environment(self): >>> return self.environment_obj.environment >>> >>> @environment.expression >>> def environment(cls): >>> return select([Environment.environment]).\ >>> where(Environment.id == >>> cls.environment_id).correlate(cls).\ >>> as_scalar() >>> >>> >>> s = Session() >>> >>> print s.query(HasEnv).filter(HasEnv.environment == 'some env') >>> >>> output: >>> >>> SELECT has_env.id AS has_env_id, has_env.environment_id AS >>> has_env_environment_id >>> FROM has_env >>> WHERE (SELECT environments.environment >>> FROM environments >>> WHERE environments."environmentID" = has_env.environment_id) = :param_1 >>> >>> wont perform well from a SQL perspective but will do the job... >>> >>> >>> >>> This worked perfectly, thank you! This is honestly a "stop-gap" measure >> to allow much of the code to be rewritten (after which it can be removed), >> and for what it's being used for at the moment, it won't be too bad >> regarding >> performance. >> >> >>> >>> but a very brief conversation with someone on the #sqlalchemy >>> channel on >>> Freenode indicated there was no way to do this and all the relevant >>> code >>> must be reworked. While it's only a few dozen places this occurs, I can >>> see >>> this coming up again in the future as further schema refactorings occur, >>> so >>> I turn to those with more expertise to find out if there is a way to >>> accomplish >>> what I desire, or if there's really no hope. :) Any insight would be >>> greatly >>> appreciated. >>> >>> I don't know how to fix this issue with IRC and stackoverflow that >>> people constantly are getting bad information. >>> >>> Heh, Sometimes I think I should know better about asking for help >> on IRC, but sometimes I get lucky. In this case, I decided I might >> have better luck on the mailing list after the answer I got on IRC >> was very unsatisfactory. :) >> >> Thanks for the help! >> > > D'oh, seems like I spoke too soon; there's a specific instance where > this fails due to some subquery stuff I'm doing: > > if apptier: > subq = ( > Session.query( > Package.pkg_name, > Package.version, > Package.revision, > AppDefinition.app_type, > AppDeployment.environment > ).join(Deployment) > .join(AppDeployment) > .join(AppDefinition) > .filter(Package.pkg_name == package_name) > .filter(AppDeployment.environment == env) > .filter(AppDeployment.status != 'invalidated')) > > [...] > > # The actual column name must be used in the subquery > # usage below; DB itself should be corrected > versions = (Session.query(subq.c.appType, > subq.c.version, > subq.c.revision) > .group_by(subq.c.appType, subq.c.environment) > .all()) > > The parts in the subquery work fine, but the access of the 'column' > in the final query leads to this: > > Traceback (most recent call last): > File "<stdin>", line 1, in <module> > File "/home/klareau/repos/git/tagopsdb/tagopsdb/deploy/deploy.py", line > 234, in find_deployed_version > .group_by(subq.c.appType, subq.c.environment) > File > "/home/klareau/.virtualenvs/tds/lib/python2.6/site-packages/sqlalchemy/util/_collections.py", > line 174, in __getattr__ > raise AttributeError(key) > AttributeError: environment > > This is not completely surprising, but I'm uncertain as the best way > to fix this... help? :) > > -- > - Ken Lareau > > -- - Ken Lareau -- You received this message because you are subscribed to the Google Groups "sqlalchemy" group. To unsubscribe from this group and stop receiving emails from it, send an email to sqlalchemy+unsubscr...@googlegroups.com. To post to this group, send email to sqlalchemy@googlegroups.com. Visit this group at http://groups.google.com/group/sqlalchemy. For more options, visit https://groups.google.com/d/optout.