I am on a mission to finally learn sqlAlchemy so that I can reap the benefits in the years to come.
I am neck deep in the sqlalchemy documents and have been for the past two days. I am hell bent on learning the classical mapping way, instead of the declarative, bc the db I want to hook up to exists, and does not have a unique id column in all of it's tables. According to this article classical mapping is the way to go under such circumstances
I have been following the classical examples from the sqlalchemy site, but I just cannot seem to find the correct relationship configuration to get this to work.
Here is all my code:
engine = create_engine(
"mssql+pyodbc://someaddress/test?driver=FreeTDS?TDS_version=8.0", echo=True)
metadata = MetaData(engine)
class User(object):
def __repr__(self):
return "<User(User_id='%s', name='%s', age='%s')>" % (
self.user_id, self.name, self.age)
class Email(object):
def __repr__(self):
return "<User(email_id='%s', address='%s', user_id='%s')>" % (
self.email_id, self.address, self.user_id)
users = Table('users', metadata,
Column('user_id', Integer, primary_key=True),
Column('name', String(40)),
Column('age', Integer),
schema='test.dbo.users')
mapper(User, users, properties={'Email': relationship(Email, primaryjoin=users.c.user_id==emails.c.user_id)})
emails = Table('emails', metadata,
Column('email_id', Integer, primary_key=True),
Column('address', String),
Column('user_id', Integer, ForeignKey('test.dbo.users.user_id')),
schema='test.dbo.emails')
mapper(Email, emails)
Session = sessionmaker(bind=engine)
session = Session()
mary = session.query(User, Email).filter(User.user_id == Email.user_id)
The pursuing error message makes it clear that it is the mapper / relationship that is the problem.
InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Original exception was: Could not determine join condition between parent/child tables on relationship User.Email - there are no foreign keys linking these tables. Ensure that referencing columns are associated with a ForeignKey or ForeignKeyConstraint, or specify a 'primaryjoin' expression.
I have tried a long list of different things to try to remedy, but I just cannot get to the bottom of it.
Any pointers in the right direction would be much appreciated!
The sqlalchemy version I am on is;
'1.0.12'
SQLAlchemy now refers to these two mapping styles as imperative mapping and declarative mapping. Regardless of what style of mapping used, all ORM mappings as of SQLAlchemy 1.4 originate from a single object known as registry , which is a registry of mapped classes.
The back_populates argument tells SqlAlchemy which column to link with when it joins the two tables. It allows you to access the linked records as a list with something like Parent.
primaryjoin – A SQL expression that will be used as the primary join of the child object against the parent object, or in a many-to-many relationship the join of the parent object to the association table.
The relationship function is a part of Relationship API of SQLAlchemy ORM package. It provides a relationship between two mapped classes. This corresponds to a parent-child or associative table relationship.
I had better luck with:
Column('user_id', Integer, ForeignKey('users.user_id')),
I also reordered the table and mapping code slightly:
users = Table('users', metadata,
Column('user_id', Integer, primary_key=True),
Column('name', String(40)),
Column('age', Integer))
emails = Table('emails', metadata,
Column('email_id', Integer, primary_key=True),
Column('address', String),
# foreign key to table users
Column('user_id', Integer, ForeignKey('users.user_id')))
mapper(Email, emails)
mapper(User, users, properties={
'Email': relationship(
Email, primaryjoin=users.c.user_id==emails.c.user_id)})
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With