Why is the code
res = Service.query.join(Counter,(Counter.service_id == Service.id)).filter(Service.dept_id == deptId).all()
print(res)
is always returning []. I want the data in array format.
My Models are as below. Please excuse me if the question is very primitive. I am very new to SQL Alchemy.
class Service(FlaskSerializeMixin,db.Model):
id = db.Column(db.Integer, primary_key=True)
ser_name = db.Column(db.String(100),unique=True,nullable=False)
ser_prefix = db.Column(db.String(1),unique=True,nullable=False)
cnt_num = db.Column(db.Integer,nullable=False)
pri_q_flg = db.Column(db.Boolean,nullable=False)
dept_id = db.Column(db.Integer, db.ForeignKey('department.id'),nullable=False)
cre_time =db.Column(db.DateTime)
chg_time =db.Column(db.DateTime)
__table_args__ = (
db.UniqueConstraint('ser_name', 'dept_id', name='unique_service_dept'),
)
pqueues = db.relationship('PQueue',backref='service',lazy=True)
counters = db.relationship('Counter',backref='service',lazy=True)
class Counter(FlaskSerializeMixin,db.Model):
id = db.Column(db.Integer, primary_key=True)
cnt_num = db.Column(db.Integer,nullable=False)
service_id = db.Column(db.Integer, db.ForeignKey('service.id'),nullable=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
cre_time =db.Column(db.DateTime)
chg_time =db.Column(db.DateTime)
__table_args__ = (
db.UniqueConstraint('cnt_num', 'service_id', name='unique_cnt_service'),
)
Related
Models:
class Cecha(db.Model):
__tablename__='cechy'
id = db.Column(db.Integer, primary_key = True)
nazwa = db.Column(db.String)
cechy_asort = db.Table('cechy_asort',
db.Column('id_cechy', db.Integer, db.ForeignKey('cechy.id')),
db.Column('id_asortymentu', db.Integer, db.ForeignKey('asortymenty.id')))
class Asortyment(db.Model):
__tablename__ = 'asortymenty'
id = db.Column(db.Integer, primary_key=True)
nazwa = db.Column(db.String(64), unique = True, index = True, nullable = False)
zamowienia = db.relationship('Zamowienie', backref='asortyment', lazy='dynamic', cascade='all,delete')
cecha = db.relationship('Cecha', secondary=cechy_asort, backref=db.backref('asortymenty', lazy='dynamic'), lazy='joined')
def ma_ceche(self, id_cechy):
cecha = Cecha.query.filter_by(id=id_cechy).first()
if cecha is None:
return False
if not cecha in self.cecha:
return False
return cecha
def dodaj_ceche(self,id_cechy):
if not self.ma_ceche(id_cechy):
cecha = Cecha.query.filter_by(id=id_cechy).first()
self.cecha.append(cecha)
db.session.commit()
def usun_ceche(self,id_cechy):
if self.ma_ceche(id_cechy):
cecha = Cecha.query.filter_by(id=id_cechy).first()
self.cecha.remove(cecha)
db.session.commit()
class Grupa_asort(db.Model):
__tablename__ = 'grupy_asort'
id = db.Column(db.Integer, primary_key=True)
nazwa = db.Column(db.String(64), unique = True, index = True)
asortymenty = db.relationship('Asortyment', backref = 'grupa_asort', lazy='dynamic', cascade='all,delete')
The problem is with deleting item from table Asortyment if there is relation:
Asortyment.query.filter_by(id_grupy=id_grupy).delete()
The error is:
cursor.execute(statement, parameters)
psycopg2.errors.ForeignKeyViolation: update or delete on table "asortymenty" violates foreign key constraint "cechy_asort_id_asortymentu_fkey" on table "cechy_asort"
DETAIL: Key (id)=(1446) is still referenced from table "cechy_asort".
cechy_asort = db.Table('cechy_asort',
db.Column('id_cechy', db.Integer, db.ForeignKey('cechy.id')),
db.Column('id_asortymentu', db.Integer, db.ForeignKey('asortymenty.id', ondelete="CASCADE")))
I have an sqlite database in my flask server with three tables as seen below:
from database import db
class ChordNode(db.Model):
__tablename__ = 'chordnode'
id = db.Column(db.Integer, primary_key=True)
hashed_id = db.Column(db.String)
successor = db.Column(db.String)
predecessor = db.Column(db.String)
is_bootstrap = db.Column(db.Boolean, default=False)
storage = db.relationship("KeyValuePair")
node_map = db.relationship("NodeRecord", cascade="delete")
def __repr__(self):
return 'Chord node {}, with successor: {}, predecessor: {}, ' \
'bootstrap: {}'.format(self.hashed_id, self.successor,
self.predecessor, self.is_bootstrap)
class KeyValuePair(db.Model):
__tablename__ = 'keyvaluepair'
id = db.Column(db.Integer, primary_key=True)
chordnode_id = db.Column(db.String, db.ForeignKey('chordnode.hashed_id'), nullable=True)
hashed_id = db.Column(db.String)
value = db.Column(db.String)
def __repr__(self):
return '<key-value pair: {}:{}, responsible Chord node: {}'.format(self.hashed_id,
self.value, self.chordnode_id)
class NodeRecord(db.Model):
__tablename__ = 'noderecord'
id = db.Column(db.Integer, primary_key=True)
bootstrap_id = db.Column(db.Integer, db.ForeignKey('chordnode.id'), nullable=False)
ip_port = db.Column(db.String)
def __repr__(self):
return 'Node record {} on boo
tstrap node with id {}'.format(self.ip_port,
self.bootstrap_id)
When i insert into ChordNode class or Noderecord everything works fine but inserting a record into KeyValuePair produces this error:
sqlalchemy.exc.IntegrityError: (sqlite3.IntegrityError) FOREIGN KEY constraint failed
However KeyValuePair's foreign key is exactly the same as ChordNode's corresponding.
Any ideas about what else could be wrong with this and why this error occurs?
I have the following models:
modifiers = db.Table('modifiers',
db.Column('modifier', db.Integer, db.ForeignKey('modifier.id')),
db.Column('modified_ingredient', db.Integer, db.ForeignKey('modified_ingredient.id')),
)
modified_ingredients = db.Table('modified_ingredients',
db.Column('recipe', db.Integer, db.ForeignKey('recipe.id')),
db.Column('modified_ingredient', db.Integer, db.ForeignKey('modified_ingredient.id'))
)
class Recipe(db.Model):
__tablename__ = 'recipe'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(256))
description = db.Column(db.Text)
directions = db.Column(db.Text)
prep_time = db.Column(db.Integer)
cook_time = db.Column(db.Integer)
image = db.Column(db.LargeBinary())
ingredients = db.relationship('ModifiedIngredient', secondary=modified_ingredients)
class Ingredient(db.Model):
__tablename__ = 'ingredient'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30), index=True, unique=True)
mod_ing = db.relationship("ModifiedIngredient")
class Modifier(db.Model):
__tablename__ = 'modifier'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(30), index=True, unique=True)
class ModifiedIngredient(db.Model):
__tablename__ = 'modified_ingredient'
id = db.Column(db.Integer, primary_key=True)
amount = db.Column(db.Integer)
unit = db.Column(db.String(20))
ingredient = db.Column(db.Integer, db.ForeignKey('ingredient.id'))
modifiers = db.relationship('Modifier', secondary=modifiers,
backref=db.backref('modifiers', lazy='dynamic'), lazy='dynamic')
I'm trying to retrieve recipes based on having two or more ingredients.
I'm able to retreive recipes that have single ingredients with the following:
db.session.query(models.Recipe).join(models.ModifiedIngredient, models.Recipe.ingredients).join(models.Ingredient).filter(models.Ingredient.name == 'garlic')
However, adding multiple filters return 0 results. This makes sense, it's matching a single ingredient to a recipe, and an ingredient can't be both garlic and onion. So, how would I accomplish this?
The solution I have found is to use an intersect.
Issue multiple queries with each of your filter options:
q1 = db.session.query(models.Recipe).join(models.ModifiedIngredient, models.Recipe.ingredients).join(models.Ingredient).filter(models.Ingredient.name == 'garlic')
q2 = db.session.query(models.Recipe).join(models.ModifiedIngredient, models.Recipe.ingredients).join(models.Ingredient).filter(models.Ingredient.name == 'onion')
q3 = q1.intersect(q2)
And q3 will have all items that have both 'onion' and 'garlic'
I've read through all of these (https://stackoverflow.com/search?q=sqlalchemy.exc.NoReferencedTableError%3A), the Flask-appbuilder docs, the sqlalchemy docs, and the Flask-sqlalchemy docs and more. Unfortunately, I can't find any full examples of a many-to-many sqlalchemy relationship.
I have a python Flask app using flask-appbuilder (which relies on flask-sqlalchemy). My app/model.py file has this:
field_feature_association = Table('field_feature_association',Base.metadata,
Column('field_id', Integer, ForeignKey('field.id')),
Column('feature_id',Integer, ForeignKey('feature.id')),
schema="main"
)
class field(Model):
__tablename__ = 'field'
id = Column(Integer, primary_key=True)
name = Column(String(70), nullable=False)
database_type = Column(String(70)) #varchar(255), text, int
joinable_to = Column(Text())
notes = Column(Text()) #don't use this for X
table_id = Column(Integer, ForeignKey('table.id'))
table = relationship("table")
features = relationship("feature",
secondary = field_feature_association,
backref = backref('fields'),
)
def __repr__(self):
return self.name
class feature(Model):
__tablename__ = 'feature'
id = Column(Integer, primary_key=True)
name = Column(String(70), unique = True, nullable=False)
field_id = Column(Integer, ForeignKey('field.id'))
#field = relationship("field")
def __repr__(self):
return self.name
It's generating this error:
sqlalchemy.exc.NoReferencedTableError: Foreign key associated with column 'field_feature_association.feature_id' could not find table 'feature' with which to generate a foreign key to target column 'id'
Thoughts on how to fix this error?
Here is a working sample of many-to-many in SQLAlchemy. Moreover I modified your model and it works fine:
field_feature_association = db.Table('field_feature_association', db.Model.metadata,
db.Column('field_id', db.Integer, db.ForeignKey('field.id')),
db.Column('feature_id', db.Integer, db.ForeignKey('feature.id')),
schema="main"
)
class Field(db.Model):
__tablename__ = 'field'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(70), nullable=False)
database_type = db.Column(db.String(70)) # varchar(255), text, int
joinable_to = db.Column(db.Text())
notes = db.Column(db.Text()) # don't use this for X
features = db.relationship("Feature",
secondary=field_feature_association,
backref=db.backref('fields'),
)
def __repr__(self):
return self.name
class Feature(db.Model):
__tablename__ = 'feature'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(70), unique=True, nullable=False)
field_id = db.Column(db.Integer, db.ForeignKey('field.id'))
# field = relationship("field")
def __repr__(self):
return self.name
and this is how to use it:
field = Field()
field.name="filed1"
feature = Feature()
feature.name = "feature1"
field.features.append(feature)
db.session.add(field)
db.session.commit()
My database object is imported as ’db’ and I have used it explicitely to refer to other types.
In my flask application with flask-sqlalchemy i need to create association between two contact
here is my Contact model
class Contact(db.Model):
__tablename__ = 'contact'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(120), nullable=False, unique=False)
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
to_contacts = db.relationship('Contact',
secondary='ContactRelation',
primaryjoin='id==contactrelation.c.from_contact_id',
secondaryjoin='id==contactrelation.c.to_contact_id',
backref='from_contacts')
and my association class ContactRelation:
class ContactRelation(db.Model):
__tablename__ = 'contactrelation'
id = db.Column(db.Integer, primary_key=True)
from_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
to_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
relation_type = db.Column(db.String(100), nullable=True)
i have error :
AttributeError: type object 'ContactRelation' has no attribute 'c'
Thanks to Michel and Simon on SQLAlchemy mailing list i need association_proxy and two relation to Contact relation.
class Contact(db.Model):
__tablename__ = 'contact'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.Unicode(120), nullable=False, unique=False)
created_on = db.Column(db.DateTime, default=datetime.utcnow)
birthday = db.Column(db.DateTime)
background = db.Column(db.Text)
photo = db.Column(db.Unicode(120))
user_id = db.Column(db.Integer, db.ForeignKey('user.id'))
to_contacts = association_proxy('to_relations', 'to_contact')
from_contacts = association_proxy('from_relations', 'from_contact')
class ContactRelation(db.Model):
__tablename__ = 'contactrelation'
id = db.Column(db.Integer, primary_key=True)
from_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
to_contact_id = db.Column(db.Integer, db.ForeignKey('contact.id'))
relation_type = db.Column(db.String(100), nullable=True)
from_contact = db.relationship(Contact,
primaryjoin=(from_contact_id == Contact.id),
backref='to_relations')
to_contact = db.relationship(Contact,
primaryjoin=(to_contact_id == Contact.id),
backref='from_relations')
Self-referential many-to-many relationship with Association Object.
User Class:
class User(Base):
__tablename__ = "User"
id = Column(String(36), primary_key=True, default=lambda : str(uuid1()))
Association Class:
class UserIgnore(Base):
__tablename__ = "UserIgnore"
id = Column(String(36), primary_key=True, default=lambda : str(uuid1()))
ignored_by_id = Column("ignored_by_id", String(36), ForeignKey("User.id"), primary_key=True)
ignored_by = relationship("User", backref="ignored_list", primaryjoin=(User.id == ignored_by_id))
ignored_id = Column("ignored_id", String(36), ForeignKey("User.id"), primary_key=True)
ignored = relationship("User", backref="ignored_by_list", primaryjoin=(User.id == ignored_id))
Access the relationship objects with
someUser.ignored_list
or
someUser.ignored_by_list
Thanks to Sean
Your relationship is not correctly designed. A secondary should be an ordinary table, not a mapped class. If you want the extra data (relation_type) on your ContactRelation, you should use the Association Table pattern described in the SQLAlchemy Relationship docs: http://docs.sqlalchemy.org/en/rel_1_1/orm/basic_relationships.html#association-object
it seems that if you change the to_contacts to something like below, your problem will be solved:
to_contacts = db.relationship('Contact',
secondary='ContactRelation',
primaryjoin='id==contactrelation.from_contact_id',
secondaryjoin='id==contactrelation.to_contact_id',
backref='from_contacts')