Error : 'str' object has no attribute 'children' - python

Thanks in advance.
When I try to display tree data from sql server, I am getting the Error:'str' object has no attribute 'children' Please help me to fix the issue.
My Code :
class Tree:
def __init__(self,name='root',children=None):
self.name=name
#self.Tid=Tid
self.children=[]
if(children):
for child in children:
self.add_child(child)
def add_child(self,node):
assert(isinstance(node,Tree))
self.children.append(node)
def __repr__(self):
return self.name
from anytree import Node, RenderTree
from anytree import ContStyle
import pyodbc
try:
cnxn = pyodbc.connect("DSN=****;database=****;trusted_connection=yes;user=****;password=****")
cursor = cnxn.cursor()
cursor.execute("select * from dbo.UserTree where Relation='self' order by Sno")
row=cursor.fetchone()
t=row[6]
print(RenderTree(t))
except Exception as e:
print("Error : ",e)
finally:
cursor.close()
cnxn.close()
FYI : output of above SQL SELECT stmt :Tree('*',[Tree('ElectronicItems',[Tree('Mobile'),Tree('TV'),Tree('Computer'),Tree('Camera'),Tree('Refrigerator')])])
Its working fine when I harcoded the value inside a variable.like this.,
t=Tree('*',[Tree('ElectronicItems',[Tree('Mobile'),Tree('TV'),Tree('Computer'),Tree('Camera'),Tree('Refrigerator')])])
print(RenderTree(t))
but throwing error when I dynamically pass the value from sql server.

If I understand you correctly, the value you are getting back from the sql statement is a string. To evaluate this string, you could use eval to interpret it during runtime:
t=eval(row[6])

Thanks Christian. it works perfect !!, Thank you Karl !!
t=eval(row[6])

Related

Python - Instantiate object from SQLite cursor

I'm running into an error when I try to instantiate an object from a cursor in SQLite and I've exhausted my research and couldn't find a solution.
Premise: I cannot use SqlAlchemy or anything of that sorts.
Assumption: The database (SQLite) works, it contains a table named table_cars, and the table is populated with data in its single column: name.
So, I have a class lets say:
class Car():
def __init__(self, name):
self.name = name
#classmethod
def from_cursor(cls, c):
car = cls(c(0))
# this line breaks when called from the function below.
And I also have a db module, with the following function:
def get_cars_from_db():
sql = 'SELECT * FROM table_cars;'
conn = get_conn()
cur = conn.cursor()
cur.execute(sql)
data = cur.fetchall()
# at this point, if i print the cursor, I can see all data, so far so good.
cars = [Car.from_cursor(c) for c in data]
# the line above causes the code to break
return cars
The code breaks with the following error:
TypeError: 'tuple' object is not callable
What am I doing wrong here?
You can use cls(c[0]) or cls(*c) to unpack tuple to function arguments.
It's also worth to specify an exact order of your columns in query.
select name from table_cars

Retrieving fields in from Mysql connection returns AttributeError: 'NoneType' object has no attribute 'format' error

I am new to Python and am trying to retrieve data from a MariaDB. Using the example found on the official documentation and tweaking with my own columns like this returns the following error:
AttributeError: 'NoneType' object has no attribute 'format'
Heres what my code looks like:
cursor.execute("SELECT id, name FROM playlists")
for id, name in cursor:
print("ID: {}, Name: {}").format(id,name)
Can someone explain why I'm getting this error? and whether I'll need to declare each column name in the for loop? (where it says for id, name in cursor
There's two issues here. one you need to save the output of the cursor.execute to a variable.
Second, you need to loop through the response. See below for an example:
import mysql.connector
from mysql.connector.cursor import MySQLCursor
db = mysql.connector.connect(option_files='my.conf', use_pure=True)
cursor = db.cursor()
cursor.execute("SELECT id, name FROM playlists")
# iterate over result
for row in cursor:
print("ID: {}, Name: {}").format(row[0],row[1])
cursor.close()
db.close()

Database insertion fails without error with scrapy

I'm working with scrapy and dataset (https://dataset.readthedocs.io/en/latest/quickstart.html#storing-data) which is a layer on top of sqlalchemy , trying to load data into a sqllite table as a follow up to Sqlalchemy : Dynamically create table from Scrapy item.
using the dataset package I have:
class DynamicSQLlitePipeline(object):
def __init__(self,table_name):
db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db"
db = dataset.connect(db_path)
self.table = db[table_name].table
def process_item(self, item, spider):
try:
print('TEST DATASET..')
self.table.insert(dict(name='John Doe', age=46, country='China'))
print('INSERTED')
except IntegrityError:
print('THIS IS A DUP')
return item
after running my spider I see the print statements printed out in the try except block, with no errors, but after completion , I look in the table and see the screenshot. No data is in the table. What am I doing wrong?
The code you posted is not working as is for me:
TypeError: __init__() takes exactly 2 arguments (1 given)
That's because the __init__ method expects a table_name argument which is not being passed. You need to implement the from_crawler class method in the pipeline object, something like:
#classmethod
def from_crawler(cls, crawler):
return cls(table_name=crawler.spider.name)
That would create a pipeline object using the spider name as table name, you can of course use any name you want.
Also, the line self.table = db[table_name].table should be replaced by self.table = db[table_name] (https://dataset.readthedocs.io/en/latest/quickstart.html#storing-data)
After that, the data is stored:
Maybe some problems with the Db connection. Put your this snippet into a try except to check for the problem.
try:
db_path = "sqlite:///"+settings.SETTINGS_PATH+"\\data.db"
db = dataset.connect(db_path)
self.table = db[table_name].table
except Exception:
traceback.exec_print()

applying function on rdd.foreach pyspark

I am trying to apply send_active_mq on each row of an rdd.
def send_to_active_mq(json_string) :
k = str(json_string)
conn.send(body=k,destination='dwEmailsQueue2')
json_rdd_to_send.foreach(send_to_active_mq)
I applied the same way as suggested in the spark documentation
http://spark.apache.org/docs/1.1.1/api/python/pyspark.rdd.RDD-class.html#foreach
But I am getting the following error.
AttributeError: 'builtin_function_or_method' object has no attribute '__code__'
Is there something fundamentally wrong I am doing here.
This is probably connected to conn object. Try:
def send_to_active_mq(json_strings):
conn = ... # Initalize connection
for json_string in json_strings:
conn.send(body=str(json_string) ,destination='dwEmailsQueue2')
json_rdd_to_send.foreachPartition(send_to_active_mq)

Commiting data from Tweepy to a sqlite3 database, no matter what I do, db remains empty

Code:
import time
import tweepy
import sqlite3
class Listener(tweepy.StreamListener):
conn = sqlite3.connect('/home/daniel/Desktop/activeSites/djeep/djeep.db')
def on_status(self, status):
try:
c = self.conn.cursor()
c.execute("""insert into feed_post values (%r,'%s','%s',%d)""") % (status.id, status.text, status.author.screen_name, status.created_at)
self.conn.commit()
except:
pass
def on_error(self, status_code):
print 'An error has occured! Status code = %s' % status_code
return True # keep stream alive
def on_timeout(self):
print 'timeout...'
def main():
auth = tweepy.OAuthHandler('C_KEY', 'C_SECRET')
auth.set_access_token('ACCESS_TOKEN', 'ACCESS_SECRET')
stream = tweepy.Stream(auth=auth, listener=Listener())
stream.filter(track=('baseball',))
if __name__=="__main__":
try:
main()
except KeyboardInterrupt:
print "See ya!"
I've gone back and added one line of the database related code at a time to try and find out what breaks it, and it seems to be the addition of the c.execute() line. I just can't figure out what I'm missing!
The path to the database should be an argument to your script, not hardcoded. It should be supplied to your class each time the class is instantiated, NOT when your class is created. However it's not apparent that that is the cause of your problem, not yet exactly what the problem is:
Your title indicates that you can't get anything written to your database, but the question body implies that something "breaks" when you add in c.execute -- which is correct? What are the symptoms when it "breaks"?
Your try\yadda\except\pass is silently ignoring all possible exceptions -- don't do that! Remove the try\except\pass leaving only the yadda, answer the above questions, and let us know the outcome.
UPDATE: Your c.execute() statement is a shocker. Making it legible without scrolling, it's equivalent to this:
(
c.execute("""insert into feed_post values (%r,'%s','%s',%d)""")
%
(status.id, status.text, status.author.screen_name, status.created_at)
)
In other words, you have a right parenthesis grossly misplaced. The result is syntactically valid, but is sure to cause an exception at run time.
Worse: you are setting yourself up for an SQL injection attack. Use parameters instead of string formatting:
sql = "insert into feed_post values (?,?,?,?)"
params = (status.id, status.text, status.author.screen_name, status.created_at)
c.execute(sql, params)
A bonus from this approach is that it should run much faster, as the engine will not need to parse (or have its cache swamped by) a typically-different SQL statement for each row written.
Try taking the self references out of the class, or use an __init__ function to initialize self.conn
def __init__(self):
self.conn = sqlite3.connect('/home/daniel/Desktop/activeSites/djeep/djeep.db')
def on_status(self, status):
try:
c = self.conn.cursor()
c.execute(SQL...)
self.conn.commit()
except:
pass
I agree with machin though, pass your connection and cursor objects as parameters when you initialize the object.

Categories

Resources