The inserts work great. But when I try to do a select query it fails with postgres. Sqlite works fine though.

Script included.

Error message:

sqlalchemy.exceptions.SQLError: ('(ProgrammingError) UNION types text and integer cannot be matched\n',)


from sqlalchemy import *
import sys, sets

# this example illustrates a polymorphic load of two classes, where each class has a very 
# different set of properties

metadata = BoundMetaData('sqlite://', echo='debug')

# a table to store companies
companies = Table('companies', metadata, 
   Column('company_id', Integer, primary_key=True),
   Column('name', String(50)))

# we will define an inheritance relationship between the table "people" and "engineers",
# and a second inheritance relationship between the table "people" and "managers"
people = Table('people', metadata, 
   Column('person_id', Integer, primary_key=True),
   Column('company_id', Integer, ForeignKey('companies.company_id')),
   Column('name', String(50)),
   Column('type', String(30)))
   
engineers = Table('engineers', metadata, 
   Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
   Column('status', String(30)),
   Column('engineer_name', String(50)),
   Column('primary_language', String(50)),
  )
   
managers = Table('managers', metadata, 
   Column('person_id', Integer, ForeignKey('people.person_id'), primary_key=True),
   Column('status', String(30)),
   Column('manager_name', String(50))
   )
   
metadata.create_all()

# create our classes.  The Engineer and Manager classes extend from Person.
class Person(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.iteritems():
            setattr(self, key, value)
    def __repr__(self):
        return "Ordinary person %s" % self.name
class Engineer(Person):
    def __repr__(self):
        return "Engineer %s, status %s, engineer_name %s, primary_language %s" % (self.name, self.status, self.engineer_name, self.primary_language)
class Manager(Person):
    def __repr__(self):
        return "Manager %s, status %s, manager_name %s" % (self.name, self.status, self.manager_name)
class Company(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.iteritems():
            setattr(self, key, value)
    def __repr__(self):
        return "Company %s" % self.name


# create a union that represents both types of joins.  
person_join = polymorphic_union(
    {
        'engineer':people.join(engineers),
        'manager':people.join(managers),
        'person':people.select(people.c.type=='person'),
    }, None, 'pjoin')

#person_mapper = mapper(Person, people, select_table=person_join, polymorphic_on=person_join.c.type, polymorphic_identity='person')
person_mapper = mapper(Person, people, select_table=person_join,polymorphic_on=person_join.c.type, polymorphic_identity='person')
mapper(Engineer, engineers, inherits=person_mapper, polymorphic_identity='engineer')
mapper(Manager, managers, inherits=person_mapper, polymorphic_identity='manager')

mapper(Company, companies, properties={
    'employees': relation(Person, lazy=False, private=True, backref='company')
})

session = create_session(echo_uow=False)
c = Company(name='company1')
c.employees.append(Manager(name='pointy haired boss', status='AAB', manager_name='manager1'))
c.employees.append(Engineer(name='dilbert', status='BBA', engineer_name='engineer1', primary_language='java'))
c.employees.append(Person(name='joesmith', status='HHH'))
c.employees.append(Engineer(name='wally', status='CGG', engineer_name='engineer2', primary_language='python'))
c.employees.append(Manager(name='jsmith', status='ABA', manager_name='manager2'))
session.save(c)

print session.new
session.flush()
#sys.exit()
session.clear()

c = session.query(Company).get(1)
for e in c.employees:
    print e, e._instance_key, e.company
assert sets.Set([e.name for e in c.employees]) == sets.Set(['pointy haired boss', 'dilbert', 'joesmith', 'wally', 'jsmith'])
print "\n"

dilbert = session.query(Person).get_by(name='dilbert')
dilbert2 = session.query(Engineer).get_by(name='dilbert')
assert dilbert is dilbert2

dilbert.engineer_name = 'hes dibert!'

session.flush()
session.clear()

c = session.query(Company).get(1)
for e in c.employees:
    print e, e._instance_key

session.delete(c)
session.flush()

metadata.drop_all()

On 16-jun-2006, at 21:03, Michael Bayer wrote:

you got it...small fix to some foreign key arithmetic in changeset 1630.

also you need to have the "from_stock" member on your InternOrder:

session.save(InternOrder(
employee=e1,
from_stock=Stock(location=Location(name='Germany'), name='SomethingElse', sellable=True),
to_stock=Stock(location=Location(name='Amsterdam'), name='Main', sellable=True)))


On Jun 16, 2006, at 12:39 PM, Koen Bok wrote:

Haha! I did exactly that this day! And it is indeed VERY cool.

I had the roof house thing working and now I am trying to implement my first question. It works, but I keep bumping into the same problem when I try to link to two tables within a polymorphic mapped class.

I think this is a bug. I included ready to roll python files.

If this is going to work, I'll be so happy!

<broken.py>
<works.py>


On 16-jun-2006, at 18:28, Michael Bayer wrote:

this assumes each House will point to a unique Roof object (i.e., its a one-to-one relationship to a Roof).  also if you use the latest trunk (or 2.3 when i release it this weekend) you can declare the mappers in any order.

houses
----------
house_id  integer pk
name       varchar

roofs
-------
roof_id integer pk
house_id integer references houses(house_id)    -- or put roof_id on the houses table, same diff
name varchar
type  varchar

concrete_roofs
--------------------
roof_id integer pk references roofs(roof_id)
hardness varchar

wood_roofs
----------------
roof_id integer pk references roofs(roof_id)
treename varchar

metadata = BoundMetaData('some://db')

(houses, roofs, concete_roofs, wood_roofs) = [Table(name, metadata, autoload=True) for name in ['houses', 'roofs', 'concrete_roofs', 'wood_roofs']]

class House(object):pass
class Roof(object):pass
class ConcreteRoof(Roof):pass
class WoodRoof(Roof):pass

mapper(House, houses, properties={
     'roof':relation(Roof, uselist=False, cascade="all, delete-orphan", backref=backref("house"))
})

roof_union = polymorphic_union(
   {
      'concrete':concrete_roofs.join(roofs),
     'wood':wood_roofs.join(roofs),
   },
    None, 'roof_union'
)
mapper(Roof, roofs, select_table=roof_union, polymorphic_on=roofs.c.type)
mapper(ConcreteRoof, concrete_roofs, inherits=Roof, polymorphic_identity='concrete')
mapper(WoodRoof, wood_roofs, inherits=Roof, polymorphic_identity='wood')


...and if that all works (which it should.....) then we really have something cool going on here...


On Jun 16, 2006, at 7:43 AM, Koen Bok wrote:

Maybe a little metaphor to make it more simple.

Let's say I make houses. The roof of the house can either be concrete or wood. Concrete and wood come in many types.

Design:

House
id
name

Wood
id
name
treename

Concrete
id
name
hardness

Now if I have a House object it should have a roof relation which either links to a Wood object or a Concrete object. It NEEDS to be linked to one of them.

Like this:

>>> house = session.query(House).get(1)
>>> print house.roof
<Concrete id=123 name=SuperBeautiful hardness=500>

>>> house = session.query(House).get(2)
>>> print house.roof
< Wood id=321 name=Oak treename='Oak Tree'>


On 16-jun-2006, at 5:24, Michael Bayer wrote:

whats wrong with this ?

order_types
---------------
type_id
name
from_stock_id
to_stock_id

?

On Jun 15, 2006, at 6:44 PM, Koen Bok wrote:

Within my organisation we have orders. Orders move products between three entities: Suppliers, Stocks and Customers.

The type of an order gets defined by the origin and the destination it is moving products. This way we can have the following types of orders:

From: To: -> Stock BUYORDER
Stock -> Supplier RETOURBUYORDER
Stock -> Stock INTERNORDER
Stock -> Customer SELLORDER
Customer ! -> Stock RETOURSELLORDER

How can I design objects/mappers to do this:

>>> order = session.query(Order).get(1)
>>> print order.type
<Type id=123 name='INTERNORDER' from=<Stock id=2> to=<Stock id=4>>

>>> order = session.query(Order).get(2)
>>> print order.type
<Type id=456 name='SELLORDER' from=<Stock id=4> to=<Customer id=1928>>
_______________________________________________
Sqlalchemy-users mailing list



_______________________________________________
Sqlalchemy-users mailing list

_______________________________________________
Sqlalchemy-users mailing list

_______________________________________________
Sqlalchemy-users mailing list

Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
Sqlalchemy-users mailing list
Sqlalchemy-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/sqlalchemy-users

Reply via email to