Hello alchemists, There's something that's been bugging me for a while now. I even asked about it on [stackoverflow][1], but it didn't get much attention there. It's been suggested to me on IRC that this mailing list might be a better place for this question.
When you take a look at the [table_per_relation ORM example][2], you can see that the argument passed to `ForeignKey` [here][3] is the “raw” “tablename.column”. However, since the entire point of declarative is to use higher-level constructs to abstract away some of the lower-level SQL details, it would make sense to me to use `cls.id` here instead. (I want this here declarative field to point to this other declarative field, instead of saying, I want this declarative field to point to this SQL column of that SQL table.) The problem is, when you try to do that, you'll get the following error: (env-tmp)koniiiik@parahippus /tmp $ python table_per_related.py 2015-10-20 13:05:44,366 INFO sqlalchemy.engine.base.Engine SELECT CAST('test plain returns' AS VARCHAR(60)) AS anon_1 2015-10-20 13:05:44,366 INFO sqlalchemy.engine.base.Engine () 2015-10-20 13:05:44,367 INFO sqlalchemy.engine.base.Engine SELECT CAST('test unicode returns' AS VARCHAR(60)) AS anon_1 2015-10-20 13:05:44,367 INFO sqlalchemy.engine.base.Engine () 2015-10-20 13:05:44,367 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("supplier_address") 2015-10-20 13:05:44,367 INFO sqlalchemy.engine.base.Engine () 2015-10-20 13:05:44,368 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("customer") 2015-10-20 13:05:44,368 INFO sqlalchemy.engine.base.Engine () 2015-10-20 13:05:44,368 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("supplier") 2015-10-20 13:05:44,368 INFO sqlalchemy.engine.base.Engine () 2015-10-20 13:05:44,368 INFO sqlalchemy.engine.base.Engine PRAGMA table_info("customer_address") 2015-10-20 13:05:44,368 INFO sqlalchemy.engine.base.Engine () Traceback (most recent call last): File "table_per_related.py", line 81, in <module> Base.metadata.create_all(engine) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/schema.py", line 3431, in create_all tables=tables) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 1726, in _run_visitor conn._run_visitor(visitorcallable, element, **kwargs) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 1357, in _run_visitor **kwargs).traverse_single(element) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/visitors.py", line 120, in traverse_single return meth(obj, **kw) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/ddl.py", line 713, in visit_metadata self.traverse_single(table, create_ok=True) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/visitors.py", line 120, in traverse_single return meth(obj, **kw) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/ddl.py", line 732, in visit_table self.connection.execute(CreateTable(table)) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 841, in execute return meth(self, multiparams, params) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/ddl.py", line 69, in _execute_on_connection return connection._execute_ddl(self, multiparams, params) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/engine/base.py", line 889, in _execute_ddl compiled = ddl.compile(dialect=dialect) File "<string>", line 1, in <lambda> File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/elements.py", line 493, in compile return self._compiler(dialect, bind=bind, **kw) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/ddl.py", line 27, in _compiler return dialect.ddl_compiler(dialect, self, **kw) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/compiler.py", line 199, in __init__ self.string = self.process(self.statement, **compile_kwargs) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/compiler.py", line 222, in process return obj._compiler_dispatch(self, **kwargs) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/visitors.py", line 80, in _compiler_dispatch return meth(self, **kw) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/compiler.py", line 2415, in visit_create_table const = self.create_table_constraints(table) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/compiler.py", line 2452, in create_table_constraints for constraint in constraints File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/compiler.py", line 2450, in <genexpr> return ", \n\t".join(p for p in File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/compiler.py", line 2458, in <genexpr> not getattr(constraint, 'use_alter', False) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/compiler.py", line 222, in process return obj._compiler_dispatch(self, **kwargs) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/sql/visitors.py", line 80, in _compiler_dispatch return meth(self, **kw) File "/tmp/env-tmp/lib/python3.4/site-packages/sqlalchemy/dialects/sqlite/base.py", line 835, in visit_foreign_key_constraint if local_table.schema != remote_table.schema: AttributeError: 'NoneType' object has no attribute 'schema' As far as I understand, this is because the `id` class attribute of `Supplier` does not get properly bound to its table; or at least, not before it is picked up by the `declared_attr` in `HasAddresses`. Several declarative constructs support passing callables for deferred evaluation, but this doesn't work for the argument passed to `ForeignKey`, since `ForeignKey` is a low-level constraint object, not a declarative one. Am I missing something here, or is there simply no way around mixing “raw” SQL identifiers with higher-level declarative classes and objects in this scenario? Cheers, Michal [1]: http://stackoverflow.com/q/33235293/687488 [2]: https://github.com/zzzeek/sqlalchemy/blob/rel_0_9/examples/generic_associations/table_per_related.py [3]: https://github.com/zzzeek/sqlalchemy/blob/rel_0_9/examples/generic_associations/table_per_related.py#L68 -- 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.
signature.asc
Description: Digital signature