On Sep 24, 2009, at 8:21 PM, David Gardner wrote:
> Ran across something that I suspect might be a bug. If I define my
> table like:
>
> asset_table = Table('asset', metadata,
> Column('path', Text, primary_key=True,
> server_default=FetchedValue(),
> server_onupdate=FetchedValue()),
> autoload=True)
>
> Then anytime I query for an asset and eagerload a related table the
> backref on the related table isn't populated, causing a second query
> to
> the DB.
> If instead I define that column of type PGText then the backrefs are
> populated properly. I attached a test which is a simplified version of
> my table mappings.
what does the logging output say if you turn on logging.INFO for the
"sqlalchemy.orm" logger ? that would illustrate some things about the
join conditions.
For me to test this I'd have to build up some table names and guess
what you have for those defaults....can you share your table
definitions ?
>
> Attached is a test of this behavior. The output when the column is
> defined as Text or String looks like:
> testshow/eps/201/s01/t01
> testshow/chr/test/test
> 2009-09-24 17:17:03,214 INFO sqlalchemy.engine.base.Engine.0x...1f10
> SELECT asset.updated AS asset_updated,
asset.name AS asset_name,
> asset.type AS asset_type, asset.path AS asset_path, asset.parent AS
> asset_parent, asset.is_file AS asset_is_file, asset.created_by AS
> asset_created_by
> FROM asset
> WHERE asset.path = %(param_1)s
> 2009-09-24 17:17:03,214 INFO sqlalchemy.engine.base.Engine.0x...1f10
> {'param_1': 'testshow/eps/201/s01/t01'}
> testshow/eps/201/s01/t01
>
>
> When defined as PGText the output is:
> testshow/eps/201/s01/t01
> testshow/chr/test/test
> testshow/eps/201/s01/t01
>
>
> --
> David Gardner
> Pipeline Tools Programmer
> Jim Henson Creature Shop
>
dgar...@creatureshop.com
>
>
> >
> import sys
> from sqlalchemy import *
> from sqlalchemy.orm import *
> from sqlalchemy.types import *
> from sqlalchemy.databases.postgres import PGText
>
> DB_HOST = 'localhost'
> DB_NAME = 'test_db'
> DB_USER = 'testuser'
> DB_PASS = 'testpass'
> db_uri = 'postgres://%s:%s@%s/%s' % (DB_USER,DB_PASS,DB_HOST,DB_NAME)
>
> db = create_engine (db_uri)
> metadata = MetaData(db)
>
> class Asset(object):
> pass
>
> class AssetRelation(object):
> pass
>
> #asset_table = Table('asset', metadata,autoload=True)
>
> #asset_table = Table('asset', metadata,
> # Column('path', Text, primary_key=True,
> # server_default=FetchedValue(),
> # server_onupdate=FetchedValue()),
> # autoload=True)
>
>
> asset_table = Table('asset', metadata,
> Column('path', PGText, primary_key=True,
> server_default=FetchedValue(),
> server_onupdate=FetchedValue()),
> autoload=True)
>
> relation_table = Table('relation',metadata, autoload=True)
>
> asset_mapper = mapper(Asset, asset_table,
> properties = {
> 'Related' : relation(AssetRelation, backref='Source',
> primaryjoin
> =
> asset_table.c.path
> =
> =
> relation_table.c.src_asset
> ,order_by=relation_table.c.target_asset,lazy=True)
> })
>
> mapper(AssetRelation, relation_table, properties = {
> 'Target' : relation(Asset, backref='Relatee',
> primaryjoin=asset_table.c.path==relation_table.c.target_asset,
> viewonly=True,lazy=False)
> })
>
> session=create_session()
> a=session.query(Asset).options(eagerload(Asset.Related)).get
> ('testshow/eps/201/s01/t01')
> db.echo=True
> print a.path
> r=a.Related[0]
> print r.target_asset
> b=r.Source
> print b.path
> session.close()
>
> sys.exit(0)