Re: [sqlalchemy] defining foreign keys?

2011-10-26 Thread Stefano Fontanelli


Hi James,
you cannot define two mapper properties that use the same name.

Your User model specifies:
addresses = relationship('Address', order_by='Address.id', backref='user')

Your Address model specifies:
user = relationship('User', backref=backref('addresses', order_by=id))

in the User model you define a backref='user', which will create a 
property 'Address.user' in the mapped entity, but it already exist!
Tha same in Address model: you define a backref named 'address' which 
already exists in User entity.


I don't know you use case but there are two scenario.

1) 'addresses' and 'user' are the end of the same relationship, in this 
case you must remove one relationship definition and use backref:


class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)

addresses = relationship('Address', order_by='Address.id', 
backref='user')



class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email_address = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey('users.id http://users.id'))


2) addresses and user properties are two different relationships, then 
you must renamed backrefs :)




Il 26/10/11 04.05, James Hartley ha scritto:

I suspect this is user error, but I am not ferreting out my mistake.

I'm porting some older code to SQLAlchemy 0.71 on top of Python 
2.7.1.  Code which had originally implemented foreign keys without 
using REFERENCES clauses in CREATE TABLE statements previously ran 
fine.  Now, adding formal foreign keys isn't working.  I have boiled 
this down to the following variant on the example found in the 
SQLAlchemy Documentation:


=8--
#!/usr/bin/env python

from sqlalchemy import create_engine, Column, ForeignKey, Integer, String
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker, relationship, backref

Base = declarative_base()

class User(Base):
__tablename__ = 'users'
id = Column(Integer, primary_key=True)
name = Column(String)
fullname = Column(String)
password = Column(String)

addresses = relationship('Address', order_by='Address.id', 
backref='user')


def __init__(self, name, fullname, password):
self.name http://self.name = name
self.fullname = fullname
self.password = password

def __repr__(self):
return User('%s', '%s', '%s', '%s') % (self.id 
http://self.id, self.name http://self.name, self.fullname, 
self.password)


class Address(Base):
__tablename__ = 'addresses'
id = Column(Integer, primary_key=True)
email_address = Column(String, nullable=False)
user_id = Column(Integer, ForeignKey('users.id http://users.id'))

user = relationship('User', backref=backref('addresses', order_by=id))

def __init__(self, email):
self.email_address = email

def __repr__(self):
return Address('%s', '%s', '%s') % (self.id 
http://self.id, self.email_address, self.user_id)


if __name__ == '__main__':
engine = create_engine('sqlite:///:memory:', echo=True)
Base.metadata.create_all(engine)
Session = sessionmaker(bind=engine)
session = Session()

user = User('jdoe', 'John Doe', 'password')
print user
session.add(user)
session.commit()
=8--

Execution yields the following traceback:

=8--
traceback (most recent call last):
  File ./test.py, line 51, in module
user = User('jdoe', 'John Doe', 'password')
  File string, line 2, in __init__
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py, 
line 309, in _new_state_if_none

state = self._state_constructor(instance, self)
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/util/langhelpers.py, 
line 432, in __get__

obj.__dict__[self.__name__] = result = self.fget(obj)
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/instrumentation.py, 
line 157, in _state_constructor

self.dispatch.first_init(self, self.class_)
  File /usr/local/lib/python2.7/site-packages/sqlalchemy/event.py, 
line 274, in __call__

fn(*args, **kw)
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py, 
line 2787, in _event_on_first_init

configure_mappers()
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py, 
line 2719, in configure_mappers

mapper._post_configure_properties()
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/mapper.py, 
line 1035, in _post_configure_properties

prop.init()
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/interfaces.py, 
line 121, in init

self.do_init()
  File 
/usr/local/lib/python2.7/site-packages/sqlalchemy/orm/properties.py, 
line 905, in do_init

self._generate_backref()
  File 

[sqlalchemy] relationship trouble

2011-10-26 Thread Jakob L.
Hi!

I added a new self-referential relationship to one of my tables but since I 
couldn't find how to create the new column through SA I added it to the db 
manually after checking how it's been done before. 

The code looks like this (using elixir):
class User(Entity):
username = Field(String(80),  primary_key=True)

# New fields
parent = ManyToOne('User')
children = OneToMany('User')

So I added a field in the db with the name parent_name since I noticed 
thats how SA names foreign keys and I also indexed it with the name 
ix_user_parent_name

Do I need to do anything else to get this to work or have I done anything 
wrong? 

What I get is:  'str' object has no attribute '_state'  for that object 
in _get_committed_attr_by_column. 

I read that this means that I add a string to a relationship object, but I 
could access the parents fields when testing. 





-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/RJ-iAdcQWDoJ.
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.



[sqlalchemy] Re: relationship trouble

2011-10-26 Thread Jakob L.
Sorry, I named the new field parent_username and the index 
 ix_user_parent_username

-- 
You received this message because you are subscribed to the Google Groups 
sqlalchemy group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/sqlalchemy/-/pPpCbKKCWnAJ.
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.



Re: [sqlalchemy] defining foreign keys?

2011-10-26 Thread Michael Bayer

On Oct 26, 2011, at 1:04 PM, James Hartley wrote:

 On Wed, Oct 26, 2011 at 2:22 AM, Stefano Fontanelli s.fontane...@asidev.com 
 wrote:
 
 Hi James,
 you cannot define two mapper properties that use the same name.
 
 Thank you.  I truly appreciate your response.  I can now implement the table 
 interconnection while both classes are defined in the same file.  My problem 
 is when the classes are separated.  Given the following two files:
 8--
 #!/usr/bin/env python
  user.py 
 from sqlalchemy import create_engine, Column, ForeignKey, Integer, String
 from sqlalchemy.ext.declarative import declarative_base
 from sqlalchemy.orm import sessionmaker, relationship, backref
 
 Base = declarative_base()
 
 class User(Base):
 __tablename__ = 'users'
 
 from user import User
 
 Base = declarative_base()
 
 class Address(Base):
 __tablename__ = 'addresses'
 
 id = Column(Integer, primary_key=True)
 email_address = Column(String, nullable=False)
 user_id = Column(Integer, ForeignKey('users.id'), nullable=False)
 
 user = relationship('User', backref=backref('addresses', order_by=id))

If you wish to locate classes based on their string name as you are doing in 
relationship('User') here, the calling class (Address) must share the same 
registry of names that the desired class (User) does.  This registry is part of 
the Base.   Therefore your entire application needs to have exactly one usage 
of declarative_base(), where all descending classes use the same Base object, 
 and not one usage per file.Additionally, both user.py and address.py must 
be imported via the Python import statement before the mappings can be used.

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



Re: [sqlalchemy] defining foreign keys?

2011-10-26 Thread James Hartley
On Wed, Oct 26, 2011 at 10:15 AM, Michael Bayer mike...@zzzcomputing.comwrote:


 On Oct 26, 2011, at 1:04 PM, James Hartley wrote:

 On Wed, Oct 26, 2011 at 2:22 AM, Stefano Fontanelli 
 s.fontane...@asidev.com wrote:


 Hi James,
 you cannot define two mapper properties that use the same name.

 If you wish to locate classes based on their string name as you are doing
 in relationship('User') here, the calling class (Address) must share the
 same registry of names that the desired class (User) does.  This registry is
 part of the Base.   Therefore your entire application needs to have
 exactly one usage of declarative_base(), where all descending classes use
 the same Base object,  and not one usage per file.


This is what I had missed.  Moving the call to declarative_base() to its own
module  importing it as needed has taken care of all remaining problems.
Thank you Michael   Stefano for taking the time to clear this up.  I
sincerely appreciate it.

Jim

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