Reputation: 1491
I'm most probably missing some basic concept here, but I have tried to create something like simple code review application and trying to follow this docs when designing DB schema:
http://flask-sqlalchemy.pocoo.org/2.1/models/#one-to-many-relationships
Part (which can be used to reproduce) of my model is:
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
# all the imports
from flask import Flask, request, session, g, redirect, url_for, \
abort, render_template, flash
from flask_sqlalchemy import SQLAlchemy
# configuration
DEBUG = True
SECRET_KEY = 'development key'
SQLALCHEMY_DATABASE_URI = 'sqlite:////tmp/test.db'
# create our little application :)
app = Flask(__name__)
app.config.from_object(__name__) # load all uppercase constants here (see configuration section above)
db = SQLAlchemy(app)
class Repo(db.Model):
id = db.Column(db.Integer, primary_key=True)
repo = db.Column(db.String(120), unique=True)
commits = db.relationship('Commit',
backref=db.backref('repo', lazy='dynamic'))
def __init__(self, repo=None):
self.repo = repo
def __repr__(self):
return '<Repo %r>' % (self.repo)
class Commit(db.Model):
id = db.Column(db.Integer, primary_key=True)
repo_id = db.Column(db.Integer, db.ForeignKey('repo.id'))
commit = db.Column(db.String(64))
def __init__(self, repo_id=None, commit=None):
self.repo_id = repo_id
self.commit = commit
def __repr__(self):
return '<Commit %r (repo %r)>' % (self.commit, self.repo_id)
if __name__ == '__main__':
app.run()
I get traceback when I attempt to create first repo:
>>> import code_review
>>> code_review.db.create_all()
>>> code_review.Repo('Pokus.git')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 2, in __init__
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", line 347, in _new_state_if_none
state = self._state_constructor(instance, self)
File "/usr/lib64/python2.7/site-packages/sqlalchemy/util/langhelpers.py", line 747, in __get__
obj.__dict__[self.__name__] = result = self.fget(obj)
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/instrumentation.py", line 177, in _state_constructor
self.dispatch.first_init(self, self.class_)
File "/usr/lib64/python2.7/site-packages/sqlalchemy/event/attr.py", line 256, in __call__
fn(*args, **kw)
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 2860, in _event_on_first_init
configure_mappers()
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 2756, in configure_mappers
mapper._post_configure_properties()
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1710, in _post_configure_properties
prop.init()
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/interfaces.py", line 183, in init
self.do_init()
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 1632, in do_init
self._generate_backref()
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/relationships.py", line 1863, in _generate_backref
mapper._configure_property(backref_key, relationship)
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/mapper.py", line 1614, in _configure_property
prop.post_instrument_class(self)
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/interfaces.py", line 526, in post_instrument_class
self.strategy.init_class_attribute(mapper)
File "/usr/lib64/python2.7/site-packages/sqlalchemy/orm/dynamic.py", line 33, in init_class_attribute
"uselist=False." % self.parent_property)
sqlalchemy.exc.InvalidRequestError: On relationship Commit.repo, 'dynamic' loaders cannot be used with many-to-one/one-to-one relationships and/or uselist=False.
Upvotes: 1
Views: 2347
Reputation: 1702
I also encounter this error while trying to typehint properly my code in python 3.8.
Previous code looked like this:
class Dealer(Base):
"""DB representation of a dealer"""
__tablename__ = "dealers_dealer"
id = Column(
BigInteger,
primary_key=True,
server_default=text("nextval('dealers_dealer_id_seq'::regclass)"),
)
name = Column(String(100), nullable=False)
invoice_email = Column(Text)
class User(Base):
__tablename__ = "users_user"
id = Column(
BigInteger,
primary_key=True,
server_default=text("nextval('users_user_id_seq'::regclass)"),
)
email = Column(String(254), nullable=False, unique=True)
dealer: Relationship[Dealer] = relationship(
"Dealer", primaryjoin="User.dealer_id == Dealer.id"
)
And was throwing two errors
sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Triggering mapper: 'Mapper[User(users_user)]'. Original exception was: On relationship User.dealer, 'dynamic' loaders cannot be used with many-to-one/one-to-one relationships and/or uselist=False.
sqlalchemy.exc.InvalidRequestError: On relationship User.dealer, 'dynamic' loaders cannot be used with many-to-one/one-to-one relationships and/or uselist=False.
Once I removed the typehint for the dealer, the error disappeared.
Upvotes: 1
Reputation: 1491
OK, I was confused by various guides and looks like this is what I want:
- commits = db.relationship('Commit',
- backref=db.backref('repo', lazy='dynamic'))
+ commits = db.relationship('Commit',
+ backref='repo', lazy='dynamic')
Upvotes: 3