On Sep 7, 2011, at 4:40 AM, werner wrote:
> or:
> Region_LV.language = sao.relationship('Language',
> primaryjoin="Country_LV.fk_language_id==Language.id",
> foreign_keys=[Country_LV.__table__.c.fk_language_id])
>
> I get:
> sqlalchemy.exc.ArgumentError: Column-based expression object expected for
> argument 'foreign_keys'; got: 'Country_LV.fk_language_id', type <type 'str'>
this one above is the one that doesn't make any sense (also its probably how
the relationship should be set up). Clearly x.__table__.c.somename is a
Column object, not a string. Something is up with what you're sending it.
I've tried to reproduce with no luck. See attached. Also I don't even need
the primaryjoin/foreignkeys if the originating Table upon which the view is
based has foreign keys to the parent.
from sqlalchemy import *
from sqlalchemy.orm import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.schema import DDLElement
from sqlalchemy.sql import table
from sqlalchemy.ext import compiler
Base= declarative_base()
# first the view stuff as it is on the wiki
class CreateView(DDLElement):
def __init__(self, name, selectable):
self.name = name
self.selectable = selectable
class DropView(DDLElement):
def __init__(self, name):
self.name = name
@compiler.compiles(CreateView)
def compile(element, compiler, **kw):
return "CREATE VIEW %s AS %s" % (element.name, compiler.sql_compiler.process(element.selectable))
@compiler.compiles(DropView)
def compile(element, compiler, **kw):
return "DROP VIEW %s" % (element.name)
def view(name, metadata, selectable):
t = table(name)
for c in selectable.c:
c._make_proxy(t)
CreateView(name, selectable).execute_at('after-create', metadata)
DropView(name).execute_at('before-drop', metadata)
return t
# now do an example using declartive
Base = declarative_base()
class MoreStuff(Base):
__tablename__ = 'morestuff'
id = Column(Integer, primary_key=True)
# if you use this one, then we don't even need the primaryjoin/foriegn_keys
# on the view, the FK propagates out
# stuff_id = Column(Integer, ForeignKey('stuff.id'))
# ... but lets say it wasn't there
stuff_id = Column(Integer)
data = Column(String(50))
class MSView(Base):
__table__ = view("msview", Base.metadata,
MoreStuff.__table__.select()
)
__mapper_args__ = {"primary_key":__table__.c.id}
# cannot reproduce your error.
class Stuff(Base):
__tablename__ = 'stuff'
id = Column(Integer, primary_key=True)
data = Column(String(50))
# works
#msview = relationship("MSView", primaryjoin="Stuff.id==MSView.stuff_id", foreign_keys="[MSView.stuff_id]")
# works
#msview = relationship("MSView", primaryjoin="Stuff.id==MSView.stuff_id", foreign_keys="MSView.stuff_id")
# doesn't work, tries to resolve __table__ as a column
#msview = relationship("MSView", primaryjoin="Stuff.id==MSView.stuff_id", foreign_keys="[MSView.__table__.c.stuff_id]")
# doesn't work, tries to resolve __table__ as a column
#msview = relationship("MSView", primaryjoin="Stuff.id==MSView.stuff_id", foreign_keys="MSView.__table__.c.stuff_id")
# works
#msview = relationship("MSView", primaryjoin="Stuff.id==MSView.stuff_id", foreign_keys=[MSView.stuff_id])
# works
msview = relationship("MSView", primaryjoin="Stuff.id==MSView.stuff_id", foreign_keys=[MSView.__table__.c.stuff_id])
# all is well
e = create_engine('sqlite://', echo=True)
Base.metadata.create_all(e)
e.execute(Stuff.__table__.insert(),
{'data':'apples'},
{'data':'pears'},
{'data':'oranges'},
{'data':'orange julius'},
{'data':'apple jacks'},
)
e.execute(MoreStuff.__table__.insert(),
{'stuff_id':3, 'data':'foobar'},
{'stuff_id':4, 'data':'foobar'}
)
s = Session(e)
print s.query(Stuff).options(eagerload("msview")).all()
--
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.