I am using Flask for my app and getting AttributeError: '_Option' object has no attribute '_sa_instance_state' error. have no idea what it is about. I google it and it seems that it is a SQL-Alchemy issue. Could you please help me with that?
here is my models.py:
#current table is used to make navigation hierarchy. eg. menu/submenu
#eg. About Us (History, Mission, Vision)
menu_hierarchy = db.Table('menu_hierarchy',
db.Column('parent_id', db.Integer, db.ForeignKey('menu.id')),
db.Column('child_id', db.Integer, db.ForeignKey('menu.id'))
)
class Menu(db.Model):
"""Menu is used for websites navigation titles.
eg. Home/About Us/Blog/Contacts/and etc"""
id = db.Column(db.Integer, primary_key = True)
title = db.Column(db.String(255))
title_eng = db.Column(db.String(255))
alias = db.Column(db.String(255))
menu_type = db.Column(db.String(10))
ordering = db.Column(db.SmallInteger, default = '1')
check_out_time = db.Column(db.DateTime)
access = db.Column(db.String(30))
published = db.Column(db.SmallInteger, default = '1')
parent_id = db.relationship('Menu',
secondary = menu_hierarchy,
primaryjoin = (menu_hierarchy.c.parent_id == id),
secondaryjoin = (menu_hierarchy.c.child_id == id),
backref = db.backref('menu_hierarchy', lazy = 'dynamic'),
lazy = 'dynamic')
content = db.Column(db.String)
content_eng = db.Column(db.String)
image = db.Column(db.String(350))
It appears the problem is related to an integer (ID) being interpreted as an ORM object.
See this SO post which includes a relevant code sample.
Related
I have a simple model.
models.py
class Content(models.Model):
title = models.CharField(max_length = 300, unique = True)
category = models.CharField(max_length = 50)
def __str__(self):
return self.title
then I'm scraping the data from some sources and want to store in this table.
toi_r = requests.get("some source")
toi_soup = BeautifulSoup(toi_r.content, 'html5lib')
toi_headings = toi_soup.findAll("h2", {"class": "entry-title format-icon"})[0:9]
toi_category = toi_soup.findAll("a", {"class": ""})[0:9]
toi_news = [th.text for th in toi_headings]
toi_cat = [tr.text for tr in toi_category]
for th in toi_headings:
toi_news.append(th.text)
for tr in toi_category:
toi_cat.append(tr.text)
for title, category in zip(toi_news, toi_cat):
n = Content.objects.create(title=title, category=category)
So here, error is UNIQUE Constraint failed. So, If I remove the UNIQUE Constraint, then everything works but mulitple copies of data are stored as the page refreshes. Is there any other way to work with this?
I try to do query in sqlalchemy to get with self-referential relationship which is filtered on parent and also child level.
category_country = Table('category_country', Base.metadata,
Column('category_id', Integer, ForeignKey('category.id'), primary_key=True),
Column('country_id', Integer, ForeignKey('country.id'), primary_key=True)
)
class Category(Base):
__tablename__ = "category"
id = Column(Integer, primary_key=True, autoincrement=True)
parent_id = Column(Integer, ForeignKey('category.id'))
subcategories = relationship("Category", backref=backref('parent', remote_side=id))
countries = relationship(Country, secondary = category_country, backref='categories')
class Country(Base):
__tablename__ = "country"
id = Column(Integer, primary_key=True)
query
category = s.query(Category).join(Category.countries).options(contains_eager(Category.countries)).filter(Country.id == 1).filter(Category.id == category_id).join(Category.countries, aliased=True).join(Category.subcategories, aliased=True).options(contains_eager(Category.countries)).filter(Country.id == 1).first()
but it doesn't work. I need to find children which are from country 1 and its parent is category_id and country is also 1
I don't completely get your model/code on my first read, but the way I would tackle this is by splitting the self-referential join into a subquery() statement like this:
filter_by_country = (db.session.query(...)
.filter(...)
.subquery())
final_results = (db.session.query(...)
.join(filter_by_country,
db.and_(Category.id == filter_by_country.c.id, ..., ...))
.options(...)
.filter(...)
.etc(...).first())
I've found this sort of a pattern can help simplify these type of queries. Hope this helps.
I have defined models:
tags = db.Table('tags',
db.Column('tag_id', db.Integer, db.ForeignKey('tag.id')),
db.Column('photo_id', db.Integer, db.ForeignKey('photo.id')),
)
class Tag(db.Model):
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(32), unique=True)
class Photo(db.Model):
id = db.Column(db.Integer, primary_key=True)
sha1sum = db.Column(db.LargeBinary(20), unique=True)
...
tags = db.relationship('Tag', secondary=tags,
backref=db.backref('photos', lazy='dynamic'))
In flask controller/view I get array of input tags for example ['summer', 'selfie', ...].
Questions:
Efficient query for photos which contain all of the requested tags?
How can it be extended for search with incomplete tags such as ['summ', 'elfi', ...]?
Might not be the most efficient (if you have many tags to search), but very readable way to compose the query:
input_tags = ['selfie', 'summer']
q = db.session.query(Photo)
for tag in input_tags:
q = q.filter(Photo.tags.any(Tag.name == tag))
For incomplete use startswith(..) instead of ==:
input_tags = ['sum', 'fu']
q = db.session.query(Photo)
for tag in input_tags:
q = q.filter(Photo.tags.any(Tag.name.startswith(tag)))
I'm having an issue with turbogears admin controller throwing an error when I try to edit the User, ShoppingItem or ShoppingList items (code below). The error coming up is AttributeError: 'function' object has no attribute 'primary_key'. The Local Variables in frame always come back as the same:
mapper
<Mapper at 0x3719810; ShoppingList>
fields
['id']
self
<sprox.sa.provider.SAORMProvider instance at 0x03E537B0>
value
<bound method OrderedProperties.items of <sqlalchemy.util._collections.OrderedProperties object at 0x037199F0>>
entity
<class 'insertmealhere.model.shoppinglist.ShoppingList'>
field_name
'items'
I'm having trouble figuring out what is different between this and the other many-to-many relationships that are configured elsewhere in the code and are not throwing this error. I'm running Turbogears 2.2 on Python 2.7.8 currently on a windows 8.1 system. Any help is greatly appreciated.
list_item_table = Table("list_item_table", metadata,
Column('item_id', Integer, ForeignKey('shopping_item.id', onupdate="CASCADE", ondelete="CASCADE"), primary_key=True),
Column('list_id', Integer, ForeignKey('shopping_list.id', onupdate="CASCADE", ondelete='CASCADE'), primary_key=True))
class ShoppingItem(DeclarativeBase):
__tablename__ = "shopping_item"
id = Column(Integer, primary_key=True)
name = Column(String(50))
quantity = Column(String(5))
measure = Column(String(10))
# less important optional parameters that will be useful for users
brand = Column(String(50))
list_id = Column(Integer, ForeignKey('shopping_list.id'))
shopping_list = relation("ShoppingList", secondary=list_item_table, backref="items")
def get_owner_id(self):
return self.list.user_id
#classmethod
def delete_list(cls, id, user_id):
item = DBSession.query(cls).filter_by(id=id).one() # get the item from the given ID
if item.get_owner_id() == user_id: # owned by current user
DBSession.delete(item) # delete from shopping list
return True
flash(_("You do not have authorization to perform that action."))
return False
class ShoppingList(DeclarativeBase):
__tablename__ = 'shopping_list'
id = Column(Integer, primary_key=True)
date = Column(Date, index=True, nullable=False)
static = Column(Boolean, nullable=False, default=False)
# static is true if the items from the meal plan have been imported into the shopping list. Once done you can edit
# the items in the shopping list, remove items, etc. Until the shopping list is made static it is impossible to edit
# the items that are imported from the schedule as they do not exist in the shopping list! (and we do not want to
# edit them in the recipe!
user_id = Column(Integer, ForeignKey('tg_user.user_id'))
user = relation("User", backref="shopping_lists")
date_user_list = Index('date_user_list', 'date', 'user_id')
Maybe it's the list_id = Column(Integer, ForeignKey('shopping_list.id')) in the ShoppingItem model class that's confusing SQLAlchemy?
I have an intermediate model -
class Link_Book_Course(models.Model):
book = models.ForeignKey(Book)
course = models.ForeignKey(Course)
image = models.CharField(max_length = 200, null=True)
rating = models.CharField(max_length = 200,null=True)
def save(self,*args,**kwargs):
self.date_created = datetime.now()
super(Link_Book_Course,self).save(*args,**kwargs)
and I need to get the book name and title (which are attributes of Book) from a specified Link_Book_Course.
This is what I've come up with, but it doesn't work- instances don't have access to the manager apparently -
storedCourse = Link_Book_Course.objects.filter(course__name= nameAndNumberStore[0] + nameAndNumberStore[1])
storedLink = Link_Book_Course.objects.filter(course = storedCourse)[0]
storeOfAuthorNames = storedLink.objects.values('book__author')
storeOfBookNames = storedLink.objects.values('book__title')
EDIT-
Nevermind, I've figured it out- for reference sake- you can't get attributes through a foreign key relationship.
Instead I filtered the Books that had the course that the user searched for.
Here's an even easier way!
>>> course = Course.objects.filter(name= nameAndNumberStore[0] + nameAndNumberStore[1])
>>> links = course.link_book_course_set.all()
>>> BookAuthorNames = [(link.book.title, link.book.author) for link in links]
(('Book1','Author1'),('Book2','Author2'),...)
Remember, the django ORM is powerful!