I am new to Python and exploring SQLAlchemy. Here is my code
class Test(Base):
__tablename__ = 'test'
__public__ = ('my_id', 'name')
my_id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, id, name):
self.my_id = id
self.name = name
def __repr__(self):
return "<User('%d','%s')>" % (self.id, self.name)
#property
def json(self):
return to_json(self, self.__class__)
users= cess.query(Test.my_id, Test.name).order_by(Test.my_id).distinct().all()
for c in users:
print c.json
But i am getting an error AttributeError: 'KeyedTuple' object has no attribute 'json' what am i doing wrong.
Kind Regards
You query is
cess.query(Test.my_id, Test.name)
so you don't get Test instances as a result. It means you don't have json property on your results. Instead you get KeyedTuples that are tuples with attributes you requested, i.e. my_id and name. To make it work you can change your query to
cess.query(Test)
Related
i am doubtful about my code. After looking for hours, was still not able to figure it out.
it's a very simple thing where i am trying to query a table with a given id. Then i want to update the 'name' attribute with the passed name.
But it's giving me an error- TypeError: 'Bucket' object does not support item assignment. it's like its not returning a dictionary
# PUT REQUEST
def put(self, id):
bucket_to_update = bucket_db.query.get(id) #### returns <Bucket id> , not dict
print(bucket_to_update) # prints the bucket as string
if not bucket_to_update:
return {"status": "failure"}, 404
args = BucketAPI.parser.parse_args()
name = args.get('name', None)
bucket_to_update['name'] = name # >>>>>>>>>>>>>>>>>>>> PRODUCES AN ERROR
db.session.commit()
return {"status" "success"}, 200
Model - Bucket / bucket_db
"""Bucket model"""
from todo_app import db
class Bucket(db.Model):
__tablename__ = 'buckets'
def __init__(self, name):
self.name = name
id = db.Column(
db.Integer,
primary_key=True
)
name = db.Column(
db.Text,
index=True,
unique=True,
nullable=False
)
items = db.relationship('Item',
backref=db.backref('bucket', lazy='joined'),
lazy=True)
def __repr__(self):
return '<bucket-{}> '.format(self.name)
From the docs and link, it is clearly visible that we can update the details as dictionary, but here its not working.
Erorr logs
bucket_to_update['name'] = name
TypeError: 'Bucket' object does not support item assignment
p.s- i am creating a Resource class to have different creation/deletion methods using flask-restful
UPDATE (solved)
As pointed on comments and answers, its an object than a dictionary, you should access it as bucket.name=name. Plus I had missed a colon while returning.
I don't have access to my coding environment but I reckon if you do following it should work fine.
bucket_to_update.name = name
Adding (3) at the end of def put(self, id):,
Correct return {"status" "success"}, 200 to return {"status":"success"}, 200
(1) In your class Bucket(db.Model): you define the initialization function __init__ so you override that of the parent class db.Model, so the __init__ function of the parent class will not be invoked.
Therefore, try:
def __init__(self, name):
db.Model.__init__(self) ## *** invoke __init__ of the parent class
self.name = name
(2) to update the modification in bucket_to_update in:
bucket_to_update['name'] = name # >>>>>>>>>>>>>>>>>>>> PRODUCES AN ERROR
db.session.commit()
add db.session.add(bucket_to_update) before commit:
bucket_to_update['name'] = name # >>>>>>>>>>>>>>>>>>>> PRODUCES AN ERROR
db.session.add(bucket_to_update)
db.session.commit()
looking for your comments.
Good Luck.
I have 2 models:
class Scenario(db.Model):
__tablename__ = 'scenarios'
scenario_id = db.Column(db.Integer, primary_key=True)
scenario_name = db.Column(db.String(120))
scenario_text = db.Column(db.Text)
hints = db.relationship('Hint', backref='scenario', lazy='dynamic')
def __init__(self, scenario_name, scenario_text):
self.scenario_name = scenario_name
self.scenario_text = scenario_text
def __repr__(self):
return "<Scenario(scenario_name='%s', scenario_text='%s', hints='%s')>" % self.scenario_name, self.scenario_text, self.hints
class Hint(db.Model):
__tablename__ = 'hints'
hint_id = db.Column(db.Integer, primary_key=True)
scenario_id = db.Column(db.Integer, db.ForeignKey('scenarios.scenario_id'))
hint = db.Column(db.Text)
release_time = db.Column(db.Integer)
def __init__(self, scenario_id, hint, release_time):
self.scenario_id = scenario_id
self.hint = hint
self.release_time = release_time
def __repr__(self):
return "<Hint(scenario_id='%s', hint='%s', release_time='%s')>" % self.scenario_id, self.hint, self.release_time
I want to be able to get all the scenarios with their corresponding hints but only the hints that have a release_time less than the current time.
I figured this would work:
scenarios = Scenario.query.filter(Scenario.hints.release_time < time.time())
But I get this error:
AttributeError: Neither 'InstrumentedAttribute' object nor 'Comparator' object associated with Scenario.hints has an attribute 'release_time'
I just started playing around with Flask and SQLAlchemy. Any advice would be appreciated.
Scenario.hints is a query, so you'll need to use a join to perform this kind of filtering.
>>> scenarios = Scenario.query.join(Hint).filter(Hint.release_time < time.time())
>>> scenarios.first()
>>> <Scenario(scenario_name='hi', scenario_text='world', hints='SELECT hints.hint_id AS hints_hint_id, hints.scenario_id AS hints_scenario_id, hints.hint AS hints_hint, hints.release_time AS hints_release_time FROM hints WHERE :param_1 = hints.scenario_id')>
See the query docs and the ORM tutorial for more details.
got problems with a Sqlalchemy thing.
I've defined my database, relevant parts as per below...
class Person(Base):
__tablename__ = 'PERSON'
#
id = Column(Integer, primary_key=True)
person_type = Column(String(32), nullable=False)
name = Column(String(50))
address = Column(String(120))
phonenum = Column(String(20))
__mapper_args__ = {'polymorphic_on':person_type}
#
class Student(Person):
__mapper_args__ = {'polymorphic_identity': 'Student'}
dob = Column(Date)
I've other subclasses of 'Person' too. I'm having problems with the way the 'init' should look. My last attempt was..
for 'Person'..
def __init__(self, a_name, a_address, a_phonenum, a_person_type = None):
self.name = a_name
self.address = a_address
self.phonenum = a_phonenum
and for 'Student'..
def __init__ (self, a_name, a_address,a_phonenum, a_dob=None, a_stud_caregiver_id=None, a_person_type = 'Student'):
self.name = a_name
self.address = a_address
self.phonenum = a_phonenum
self.dob = a_dob
self.stud_caregiver_id = a_stud_caregiver_id
self.person_type = a_person_type
but though this creates the database ok, when I come to 'init' my students, I'm getting messages along the lines of...
sqlalchemy.exc.InvalidRequestError: One or more mappers failed to initialize - can't proceed with initialization of other mappers. Original exception was: Class object expected, got 'Table('PERSON', MetaData(bind=None)....
I've tried with/without the person_type parameter .. but really, I'm just shooting in the dark.
I've obviously done something dumb, but what? Thanks!
I am new to Python. Here is my code
class Test(Base):
__tablename__ = 'test'
__public__ = ('my_id', 'name')
my_id = Column(Integer, primary_key=True)
name = Column(String)
def __init__(self, id, name):
self.my_id = id
self.name = name
def __repr__(self):
return "<User('%d','%s')>" % (self.id, self.name)
#property
def json(self):
return to_json(self, self.__class__)
output=[]
users= cess.query(Test).order_by(Test.my_id).distinct().all()
for c in users:
output.append(c.json)
print json.dumps(output)
But this is not correct json? I want to add all the json objects from the for loop into a proper json array, so the client can loop over it ? How can i do this ?
You can construct a list of dicts from your query results. Define to_dict method on your model (taken from here):
class Test(Base):
...
def to_dict(self):
return {c.name: getattr(self, c.name) for c in self.__table__.columns}
Then, make a list of dicts and dump it to json:
users = cess.query(Test).order_by(Test.my_id).distinct().all()
output = [c.to_dict() for c in users]
print json.dumps(output)
Also see:
How to serialize SqlAlchemy result to JSON?
jsonify a SQLAlchemy result set in Flask
Getting this error when I try to instantiate the ConsumerAdvice class.
Foreign key associated with column 'tbConsumerAdvice.ConsumerAdviceCategory_ID'
could not find table 'tbConsumerAdviceCategories' with which to generate a
foreign key to target column 'ID_ConsumerAdviceCategories'
class ConsumerAdviceCategory(Base):
__tablename__ = 'tbConsumerAdviceCategories'
__table_args__ = {'schema':'dbo'}
ID_ConsumerAdviceCategories = Column(INTEGER, Sequence('idcac'),\
primary_key=True)
Name = Column(VARCHAR(50), nullable=False)
def __init__(self,Name):
self.Name = Name
def __repr__(self):
return "< ConsumerAdviceCategory ('%s') >" % self.Name
class ConsumerAdvice(Base):
__tablename__ = 'tbConsumerAdvice'
__table_args__ = {'schema':'dbo'}
ID_ConsumerAdvice = Column(INTEGER, Sequence('idconsumeradvice'),\
primary_key=True)
ConsumerAdviceCategory_ID = Column(INTEGER,\
ForeignKey('tbConsumerAdviceCategories.ID_ConsumerAdviceCategories'))
Name = Column(VARCHAR(50), nullable=False)
Category_SubID = Column(INTEGER)
ConsumerAdviceCategory = relationship("ConsumerAdviceCategory",\
backref=backref('ConsumerAdvices'))
def __init__(self,Name):
self.Name = Name
def __repr__(self):
return "< ConsumerAdvice ('%s') >" % self.Name
Define the FK including schema: dbo.tbConsumerAdviceCategories.ID_ConsumerAdviceCategories
I also hit this error. In my case the root cause was that I attempted to define different sqlalchemy base classes:
Base1 = declarative_base(cls=MyBase1)
Base1.query = db_session.query_property()
Base2 = declarative_base(cls=MyBase2)
Base2.query = db_session.query_property()
I had a ForeignKey relationship from one class that derives from Base1 to another class that derives from Base2. This didn't work -- I got a similar NoReferencedTableError. Apparently classes must derive from the same Base class in order to know about each other.
Hope this helps someone.
That didn't solve my problem, I had to use.
ConsumerAdviceCategory_ID = Column(INTEGER,
ForeignKey('tbConsumerAdviceCategories.ID_ConsumerAdviceCategories',
schema='dbo'))