Gregg Lind wrote:
> What I think I'm seeing is that an object can be created even without it's
> ForeignKeyConstraint being filled.
>
> To run the test code below:
>
> $ dropdb test18; createdb test18; python testcode.py

"on" is not defined:

ForeignKeyConstraint(['regstring_id', 'regstring','regstring_type'],
[A1String.id, A1String.string, A1String.origin], on),

when removing "on", the row inserts with "regstring_id" as NULL.  PG
appears to accept this so I would assume PG considers a three-column
foreign key with one NULL to be NULL.  If I try it with all three columns
not null, then you get the constraint error.


SQLalchemy itself relies upon the database to enforce constraints.    In
this case you should have the "NOT NULL" constraint on the Product
columns.






>
> This builds on
> http://groups.google.com/group/sqlalchemy/browse_thread/thread/eb240f3f2555a5e7/
> .
>
> I understand that the foreign table can't create the referent.  (and
> finding
> the best idiom for "use one if it exists or create one") is yet be
> determined.  What I truly don't understand is how any instances of
> "Product"
> can be created, since there is a FK constraint that is not fulfulled.
>
> 1.  Is the foreign key constraint fulfilled?
> 2.  Is there a good "create the referent if it doesn't exist, else use it"
> idiom?
> 3.  Is the polymorphic table business complicating it?  It seems liek the
> compound primary key for A1String is.
>
> ----------------
> from sqlalchemy.ext.declarative import
> declarative_base
> from sqlalchemy import CheckConstraint, ForeignKey, MetaData,
> PrimaryKeyConstraint
> from sqlalchemy import ForeignKeyConstraint
> from sqlalchemy import Table, Column, Integer, Boolean,Unicode,String
> from sqlalchemy.orm import relation, backref
> from sqlalchemy import create_engine
> from sqlalchemy.orm import sessionmaker
> from sqlalchemy.schema import DDL
>
> import sys
> ECHO = bool((sys.argv + [False])[1])
>
> ## utilties for connecting the db, printing it, etc.
> def print_schema(T="postgres", Base=None):
>     ''' print print_schema will print the schema in use '''
>     from StringIO import StringIO
>     buf = StringIO()
>     engine = create_engine('%s://' % T, strategy='mock', executor=lambda
> s,
> p='': buf.write(str(s) + p))
>     Base.metadata.create_all(engine)
>     return buf.getvalue()
>
> def db_setup(connstring='sqlite:///:memory:', echo=False, Base=None):
>     engine = create_engine(connstring, echo=echo)
>     Session = sessionmaker(bind=engine, autoflush=False, autocommit=False)
>     session = Session()
>     Base.metadata.bind = engine
>     Base.metadata.create_all()
>     return session, engine
>
> def _class_repr(self):
>     ''' print our SA class instances in a nicer way '''
>     # ugly, use sparingly, may have performance hit
>     d = [(k,v) for k,v in self.__dict__.iteritems() if k[0] != "_"]
>     d = sorted(d, key=lambda x: x[0].lower())
>     return "<%s, %s>" % (self.__class__, d)
>
>
> Base = declarative_base()
>
> class Polystring(Base):
>     __tablename__ = 'strings'
>     id = Column(Integer, nullable=False, primary_key=True)
>     string = Column(String, nullable=False, primary_key=True)
>     origin = Column(String, nullable=False, primary_key=True)
>     __mapper_args__ = {'polymorphic_on': origin}
>
> # subtype of string
> class A1String(Polystring):
>     __mapper_args__ = {'polymorphic_identity': 'a1'}
>     products = relation('Product', order_by="Product.id")
>
> class Product(Base):
>     __tablename__ = 'product'
>     __table_args__ = (
>          ForeignKeyConstraint(['regstring_id', 'regstring',
> 'regstring_type'], [A1String.id, A1String.string
> , A1String.origin], on),
>         {}
>     )
>     id = Column(Integer,primary_key=True)
>     regstring_id = Column(Integer)
>     regstring = Column(String)
>     regstring_type = Column(String,default="asn")
>
>
>
> ## test code
> session,eng = db_setup("postgres:///test18", Base=Base, echo=ECHO)
> add = session.add
> q = session.query
> c = session.commit
> r = _class_repr
>
>
> A = Product(id=192832, regstring="some part id")
> print r(A)
> add(A)
> c()  # commit
> print map(r,q(Product).all())
> print "somehow this managed to get in, without making a polystring, which
> it
> should be referencing."
> assert len(q(Polystring).all()) > 0, "So, where is the polystring?"
> ----------
>
> >
>


--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to