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 [email protected].
To post to this group, send email to [email protected].
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
