On 09/02/2016 04:37 PM, Mike Bayer wrote:


On 09/02/2016 10:25 AM, TomS. wrote:

On 08/30/2016 08:25 PM, Mike Bayer wrote:


On 08/30/2016 01:54 PM, TomS. wrote:
Hi,

I would like to create an abstract model which should be inherited.
Unfortunately, I am not allowed to used Foreign Keys, this is the reason
why I introduced work around via relationship. Here is the whole code:

class DepTest(db.Model):

    __tablename__ = u'deptest'
    __bind_key__ = u'section'

    department_pk_id = db.Column(db.Integer, primary_key=True)
    department_id = db.Column(db.Integer)
    department_name = db.Column(db.String(1000))


class PPLTest(db.Model):

    __abstract__ = True

    person_pk_id = db.Column(db.Integer, primary_key=True)
    person_name = db.Column(db.String(1000))
    person_surname = db.Column(db.String(1000))
    department_id = db.Column(db.Integer)

    @hybrid_property
    def person_name_surname(self):
        return self.person_name + u' ' + self.person_surname


class Level1(PPLTest):

    __tablename__ = u'ppl_level1'
    __bind_key__ = u'section'

    department = relationship(
        DepTest,
        primaryjoin=remote(DepTest.department_id) == foreign(
            PPLTest.department_id))


But I get "Cannot compile Column object until its 'name' is assigned."

So I defined department (in Level1) using @declared_attr:

    def department(clss):
        return relationship(DepTest,
                            primaryjoin=lambda:
remote(DepTest.department_id) == foreign(
                                clss.department_id)
                            )

and now it works as expected. The question is - is it defined properly,
or I should be aware of sth?

Yes, using a lambda here, or alternatively using a string-eval, is a
good way to defer evaluation of that primaryjoin until declarative has
set things up and put names in your Column objects.

Just curious to see the stack trace here because I don't see where the
Column needs to actually be compiled into a string.
Thank you!

Flask==0.10.1
Flask-SQLAlchemy==2.0
SQLAlchemy==1.0.14

Here it is:


OH. ha, weird. OK, that was it trying to raise a different error, "Could not locate any simple equality expressions "\
                "involving locally mapped foreign key columns for "\
                "%s join condition "\
                "'%s' on relationship %s."

But that failed because it couldn't turn the join condition into a string.

But w/ lambda you don't get that error either huh ?
It happens when Level1 is defined this way:

    department = relationship(
        DepTest,
        primaryjoin=remote(DepTest.department_id) == foreign(
            PPLTest.department_id))

    # @declared_attr
    # def department(clss):
    #     return relationship(DepTest,
# primaryjoin=lambda: remote(DepTest.department_id) == foreign(
    #                             clss.department_id)
    #                         )

It is ok when defintion is as follows (with or without lambda):

    # department = relationship(
    #     DepTest,
    #     primaryjoin=remote(DepTest.department_id) == foreign(
    #         PPLTest.department_id))

    @declared_attr
    def department(clss):
        return relationship(DepTest,
primaryjoin=lambda: remote(DepTest.department_id) == foreign(
                                clss.department_id)
                            )






Traceback (most recent call last):
  File "testing.py", line 20, in <module>
    q = testm.Level1.query.all()
  File
"/test/_env/lib/python2.7/site-packages/flask_sqlalchemy/__init__.py",
line 452, in __get__
    mapper = orm.class_mapper(type)
  File "/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/base.py",
line 421, in class_mapper
    mapper = _inspect_mapped_class(class_, configure=configure)
  File "/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/base.py",
line 400, in _inspect_mapped_class
    mapper._configure_all()
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line
1167, in _configure_all
    configure_mappers()
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line
2770, in configure_mappers
    mapper._post_configure_properties()
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py", line
1710, in _post_configure_properties
    prop.init()
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/interfaces.py",
line 183, in init
    self.do_init()
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line
1629, in do_init
    self._setup_join_conditions()
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line
1704, in _setup_join_conditions
    can_be_synced_fn=self._columns_are_mapped
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line
1977, in __init__
    self._check_foreign_cols(self.primaryjoin, True)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/orm/relationships.py", line
2481, in _check_foreign_cols
    self.prop
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/elements.py",
line 506, in __str__
    return unicode(self.compile()).encode('ascii', 'backslashreplace')
  File "<string>", line 1, in <lambda>
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/elements.py",
line 494, in compile
    return self._compiler(dialect, bind=bind, **kw)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/elements.py",
line 500, in _compiler
    return dialect.statement_compiler(dialect, self, **kw)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",
line 395, in __init__
    Compiled.__init__(self, dialect, statement, **kwargs)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",
line 190, in __init__
    self.string = self.process(self.statement, **compile_kwargs)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",
line 213, in process
    return obj._compiler_dispatch(self, **kwargs)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py",
line 93, in _compiler_dispatch
    return meth(self, **kw)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",
line 927, in visit_binary
    return self._generate_generic_binary(binary, opstring, **kw)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",
line 944, in _generate_generic_binary
    binary.right._compiler_dispatch(self, **kw)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/annotation.py",
line 73, in _compiler_dispatch
    self, visitor, **kw)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/visitors.py",
line 81, in _compiler_dispatch
    return meth(self, **kw)
  File
"/test/_env/lib/python2.7/site-packages/sqlalchemy/sql/compiler.py",
line 627, in visit_column
    raise exc.CompileError("Cannot compile Column object until "
sqlalchemy.exc.CompileError: Cannot compile Column object until its
'name' is assigned.






Thank you for any suggestions!

Cheers





--
You received this message because you are subscribed to the Google Groups 
"sqlalchemy" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to sqlalchemy+unsubscr...@googlegroups.com.
To post to this group, send email to sqlalchemy@googlegroups.com.
Visit this group at https://groups.google.com/group/sqlalchemy.
For more options, visit https://groups.google.com/d/optout.

Reply via email to