I am trying to put data into a database using flask and peewee, and I have come across the following error: peewee.OperationalError: no such table: post
My models.py file is below:
from peewee import *
import datetime
db = SqliteDatabase('posts.db') #create database to interact with
#create a class for blogposts
class Post(Model):
id = PrimaryKeyField()
date = DateTimeField(default = datetime.datetime.now)
title = CharField()
text = TextField()
class Meta:
database = db
def initialize_db():
db.connect()
db.create_tables([Post], safe = True)
db.close()
I have Googled this, and for most people the lack of 'db.create_tables()' seems to be the problem. Obviously, it's in my code, so I am really not sure where the error is coming from. Some advice would be much appreciated. The problem seems to arise specifically when I try to populate the 'text' field using another .py file.
I adapted your code into the following snippet and it works for me:
from peewee import *
import datetime
db = SqliteDatabase('posts.db') #create database to interact with
#create a class for blogposts
class Post(Model):
id = PrimaryKeyField()
date = DateTimeField(default = datetime.datetime.now)
title = CharField()
text = TextField()
class Meta:
database = db
def initialize_db():
db.connect()
db.create_tables([Post], safe = True)
db.close()
initialize_db() #if db tables are not created, create them
post = Post.create(id=4, title="Some title", text="some text1") #add a new row
post.save() #persist it to db, not necessarily needed
You'll need to call the create method when creating a new Post (i.e. a new row in your database). Other than that, initialize_db() seems to work just fine.
If you are unable to perform any writes on the database, make sure you have write access in the directory where you are trying to do that (in this case, it would be your working directory)
Related
I have been developing a flask based app for my college event. I have used an SQLite database along with Peewee and it's playhouse extensions. There is a particular page where I need to show all the entries from a database table.
# The playhouse.flask_utils.FlaskDB object accepts database URL configuration.
DATABASE = 'sqliteext:///%s' % os.path.join(APP_DIR, 'blog.db')
DEBUG = False
# Create a Flask WSGI app and configure it using values from the module.
app = Flask(__name__)
app.config.from_object(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
# FlaskDB is a wrapper for a peewee database that sets up pre/post-request
# hooks for managing database connections.
flask_db = FlaskDB(app)
# The `database` is the actual peewee database, as opposed to flask_db which is
# the wrapper.
database = flask_db.database
There is an Entry class, with save and a query function
class Entry(flask_db.Model):
title = CharField()
slug = CharField(unique=True)
content = TextField()
tags = TextField()
published = BooleanField(index=True)
is_highlight = BooleanField(index=True)
category = TextField()
date = TextField()
time = TextField()
contact = TextField()
fee = TextField()
image = TextField()
timestamp = DateTimeField(default=datetime.datetime.now, index=True)
#property
def html_content(self):
"""
Generate HTML representation of the markdown-formatted blog entry,
and also convert any media URLs into rich media objects such as video
players or images.
"""
hilite = CodeHiliteExtension(linenums=False, css_class='highlight')
extras = ExtraExtension()
markdown_content = markdown(self.content, extensions=[hilite, extras])
oembed_content = parse_html(
markdown_content,
oembed_providers,
urlize_all=True,
maxwidth=app.config['SITE_WIDTH'])
return Markup(oembed_content)
def save(self, *args, **kwargs):
# Generate a URL-friendly representation of the entry's title.
if not self.slug:
self.slug = re.sub('[^\w]+', '-', self.title.lower()).strip('-')
ret = super(Entry, self).save(*args, **kwargs)
# Store search content.
return ret
#classmethod
def public(cls):
return Entry.select().where(Entry.published == True)
And the function that renders the page is
#app.route('/events')
def events():
query = Entry.public()
return object_list(
'list.html',
query,
check_bounds=False)
The query when run over the command line using sqlite3 for ubuntu returns all 26 entries, however in the app, it returns only 20 of them. I verified by deleting one of the entries from the table, and it's place was taken by one of the rows not visible earlier. I looked upon multiple sites and documentations from both peewee and sqlite and haven't found a solution yet. I even tried changing pragma statements like Page Size. I am of the opinion that changing the run-time limits of the DB can help me, but I haven't found a way to change or modify that. Is there anyway to fix it. Or is migration to MariaDB gonna solve it. If so is that the only solution.
I simply had to use 'paginate_by = my-number' in the object list.
I am probably asking an obvious thing, but I could not find the answer.
I am learning Pony ORM, and started with creating simple database from the documentation. I made a design of a simple database diagram and code https://editor.ponyorm.com/user/nidza11/Ponz#
from pony.orm import *
db = Database()
class Person(db.Entity):
id = PrimaryKey(int, auto=True)
name = Required(str)
age = Required(int)
cars = Set('Car', cascade_delete=True)
class Car(db.Entity):
id = PrimaryKey(int, auto=True)
make = Required(str)
model = Required(str)
person = Required(Person)
db.bind("sqlite", "TestDB.sqlite", create_db = True)
db.generate_mapping(create_tables=True)
with db_session:
p1 = Person(name="John", age=24)
p2 = Person(name="Ive", age=26)
p3 = Person(name="Olivia", age = 26)
c1 = Car(make="Toyota", model = "Prius", person = p2)
p3 = Car(make="Ford", model = "Explorer", person = p3)
After running the code, database was created and populated.
I would like to make a name attribute in Person table unique. So I made a change in code
name = Required(str, unique=True)
After running the code again database was populated, but the name field is not set unique. Data was duplicated. According to DB browser name field was 'unique'. I expected an error. Such error will help me keep entity and database synchronized.
Adding a new attribute only in Person table class, but not in database, will cause an error.
Is it possible to make a change only in one place inside the code, that will reflect in database as well?
If I have to make a same change on two places, how to do it nice and clean?
I've just asked on the Pony ORM 'Telegram' group and this is the transaction that occurred there.
I met an transaction problem when I used the python orm peewee these days. I save two book instances using this orm, and beween the two savings I raise an exception so I except that none of them are saved to database, but it doesn't work. Could anyone explain why? I am new to python, thanks.
this code is below:
from peewee import *
def get_db():
return SqliteDatabase("test.db")
class Book(Model):
id = PrimaryKeyField()
name = CharField()
class Meta:
database = get_db()
def test_transaction():
book1 = Book(name="book1")
book2 = Book(name="book2")
db = get_db()
db.create_tables([Book], safe=True)
try:
with db.transaction() as tran:
book1.save()
raise ProgrammingError("test")
book2.save()
except:
pass
for book in Book.select():
print(book.name)
if __name__ == '__main__':
test_transaction()
The problem is that when you are calling "get_db()" you are instantiating new database objects. Databases are stateful, in that they manage the active connection for a given thread. So what you've essentially got is two different databases, one that your models are associated with, and one that has your connection and transaction. When you call db.transaction() a transaction is taking place, but not on the connection you think it is.
Change the code to read as follows and it will work like you expect.
book1 = Book(name='book1')
book2 = Book(name='book2')
db = Book._meta.database
# ...
I have read the Peewee MySQL API documentation and this question; however, what I do not understand is how to connect to a specified table in a db using Peewee. Essentially all I'm trying to do is connect to a a table called Persons in a db called as_schema, set up some sort of basic object-relational mapping, and print out all entries' aNum column values.
My table Persons that I'm trying to read from has the following columns:
varchar called aNum
bool called access
bool called ajar
bool called ebr
date called weekof
My code consists of the following:
import peewee
from peewee import *
db = MySQLDatabase('as_schema', user='root',passwd='')#this connection path works perfectly, tried it using the standard MySQLdb.connect
class Person(Model):
class Meta:
database = db
class User(Person):
aNum = CharField()
Person.create_table()
person = User(aNum = 'a549189')
person.save();
for person in Person:
print person.aNum
The error I'm getting is:
class Person(Model):
class Meta:
database = db
db_table = 'Persons' # Add this.
In the docs, you can find a list of supported meta options:
http://docs.peewee-orm.com/en/latest/peewee/models.html#model-options-and-table-metadata
I am a newbie to python. I am not able to query from the entities- UserDetails and PhoneBook I loaded to the app engine datastore. I have written this UI below based on the youtube video by Brett on "Developing and Deploying applications on GAE" -- shoutout application. Well I just tried to do some reverse engineering to query from the datastore but failed in every step.
#!/usr/bin/env python
import wsgiref.handlers
from google.appengine.ext import db
from google.appengine.ext import webapp
from google.appengine.ext.webapp import template
import models
class showPhoneBook(db.Model):
""" property to store user_name from UI to persist for the session """
user_name = db.StringProperty(required=True)
class MyHandler(webapp.RequestHandler):
def get(self):
## Query to get the user_id using user_name retrieved from UI ##
p = UserDetails.all().filter('user_name = ', user_name)
result1 = p.get()
for itr1 in result1:
userId = itr.user_id
## Query to get the phone book contacts using user_id retrieved ##
q = PhoneBook.all().filter('user_id = ', userId)
values = {
'phoneBookValues': q
}
self.request.out.write(
template.render('phonebook.html', values))
def post(self):
phoneBookuser = showPhoneBook(
user_name = self.request.get('username'))
phoneBookuser.put()
self.redirect('/')
def main():
app = webapp.WSGIApplication([
(r'.*',MyHandler)], debug=True)
wsgiref.handlers.CGIHandler().run(app)
if __name__ == "__main__":
main()
This is my models.py file where I've defined my UserDetails and PhoneBook classes,
#!/usr/bin/env python
from google.appengine.ext import db
#Table structure of User Details table
class UserDetails(db.Model):
user_id = db.IntegerProperty(required = True)
user_name = db.StringProperty(required = True)
mobile_number = db.PhoneNumberProperty(required = True)
#Table structure of Phone Book table
class PhoneBook(db.Model):
contact_id = db.IntegerProperty(required=True)
user_id = db.IntegerProperty(required=True)
contact_name = db.StringProperty(required=True)
contact_number = db.PhoneNumberProperty(required=True)
Here are the problems I am facing,
1) I am not able to call user_name (retrieved from UI-- phoneBookuser = showPhoneBook(user_name = self.request.get('username'))) in get(self) method for querying UserDetails to to get the corresponding user_name.
2) The code is not able to recognize UserDetails and PhoneBook classes when importing from models.py file.
3) I tried to define UserDetails and PhoneBook classes in the main.py file itself, them I get the error at result1 = p.get() saying BadValueError: Unsupported type for property : <class 'google.appengine.ext.db.PropertiedClass'>
I have been struggling since 2 weeks to get through the mess I am into but in vain. Please help me out in straightening out my code('coz I feel what I've written is a error-prone code all the way).
I recommend that you read the Python documentation of GAE found here.
Some comments:
To use your models found in models.py, you either need to use the prefix models. (e.g. models.UserDetails) or import them using
from models import *
in MyHandler.get() you don't lookup the username get parameter
To fetch values corresponding to a query, you do p.fetch(1) not p.get()
You should also read Reference properties in GAE as well. I recommend you having your models as:
class UserDetails(db.Model):
user_name = db.StringProperty(required = True)
mobile_number = db.PhoneNumberProperty(required = True)
#Table structure of Phone Book table
class PhoneBook(db.Model):
user = db.ReferenceProperty(UserDetails)
contact_name = db.StringProperty(required=True)
contact_number = db.PhoneNumberProperty(required=True)
Then your MyHandler.get() code will look like:
def get(self):
## Query to get the user_id using user_name retrieved from UI ##
user_name = self.request.get('username')
p = UserDetails.all().filter('user_name = ', user_name)
user = p.fetch(1)[0]
values = {
'phoneBookValues': user.phonebook_set
}
self.response.out.write(template.render('phonebook.html', values))
(Needless to say, you need to handle the case where the username is not found in the database)
I don't quite understand the point of showPhoneBook model.
Your "session variable" being stored to the datastore isn't going to follow your redirect; you'd have to fetch it from the datastore in your get() handler, although without setting a session ID in a cookie or something this isn't going to implement sessions at all, but rather allow anyone getting / to use whatever value was send with a POST request whether it was sent by them or someone else. Why use the redirect at all; responding to a POST request should be done in the post() method, not through a redirect to a GET method.