Python Forum

Full Version: Create SQLite3 database with peewee
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Hello everybody,

I begin with peewee to create SQLite database. When I use the python code example supplied with the documentation, all works correctly but when I do some minor changes (from my point of view), the database is created but an error occurs and the tables are not cretaed.

Peewee original code example :
from peewee import *

# create a peewee database instance -- our models will use this database to
# persist information
DATABASE = SqliteDatabase("test.db")
    
def create_tables():
    with DATABASE as db:
        db.create_tables([User, Relationship, Message])

# model definitions -- the standard "pattern" is to define a base model class
# that specifies which database to use.  then, any subclasses will automatically
# use the correct storage.
class BaseModel(Model):
    class Meta:
        database = DATABASE

# the user model specifies its fields (or columns) declaratively, like django
class User(BaseModel):
    username = CharField(unique=True)
    password = CharField()
    email = CharField()
    join_date = DateTimeField()

# this model contains two foreign keys to user -- it essentially allows us to
# model a "many-to-many" relationship between users.  by querying and joining
# on different columns we can expose who a user is "related to" and who is
# "related to" a given user
class Relationship(BaseModel):
    from_user = ForeignKeyField(User, backref='relationships')
    to_user = ForeignKeyField(User, backref='related_to')

    class Meta:
        # `indexes` is a tuple of 2-tuples, where the 2-tuples are
        # a tuple of column names to index and a boolean indicating
        # whether the index is unique or not.
        indexes = (
            # Specify a unique multi-column index on from/to-user.
            (('from_user', 'to_user'), True),
        )

# a dead simple one-to-many relationship: one user has 0..n messages, exposed by
# the foreign key. a users messages will be accessible as a special attribute,
# User.messages.
class Message(BaseModel):
    user = ForeignKeyField(User, backref='messages')
    content = TextField()
    pub_date = DateTimeField()
    

if __name__ == "__main__":
    create_tables()


Similar code with minor change :
from peewee import *

# create a peewee database instance -- our models will use this database to
# persist information
DATABASE = None
    
def create_tables():
    with DATABASE as db:
        db.create_tables([User, Relationship, Message])

# model definitions -- the standard "pattern" is to define a base model class
# that specifies which database to use.  then, any subclasses will automatically
# use the correct storage.
class BaseModel(Model):
    class Meta:
        database = DATABASE

# the user model specifies its fields (or columns) declaratively, like django
class User(BaseModel):
    username = CharField(unique=True)
    password = CharField()
    email = CharField()
    join_date = DateTimeField()

# this model contains two foreign keys to user -- it essentially allows us to
# model a "many-to-many" relationship between users.  by querying and joining
# on different columns we can expose who a user is "related to" and who is
# "related to" a given user
class Relationship(BaseModel):
    from_user = ForeignKeyField(User, backref='relationships')
    to_user = ForeignKeyField(User, backref='related_to')

    class Meta:
        # `indexes` is a tuple of 2-tuples, where the 2-tuples are
        # a tuple of column names to index and a boolean indicating
        # whether the index is unique or not.
        indexes = (
            # Specify a unique multi-column index on from/to-user.
            (('from_user', 'to_user'), True),
        )

# a dead simple one-to-many relationship: one user has 0..n messages, exposed by
# the foreign key. a users messages will be accessible as a special attribute,
# User.messages.
class Message(BaseModel):
    user = ForeignKeyField(User, backref='messages')
    content = TextField()
    pub_date = DateTimeField()
    

if __name__ == "__main__":
    DATABASE = SqliteDatabase("test.db")
    create_tables()
Please find below the trace back of the error :
Error:
Traceback (most recent call last): File "c:\Users\Dell\Documents\Jean-Marie\supaiment\server_app\dbsupaiement.py", line 53, in <module> create_tables() File "c:\Users\Dell\Documents\Jean-Marie\supaiment\server_app\dbsupaiement.py", line 9, in create_tables db.create_tables([User, Relationship, Message]) File "C:\Users\Dell\AppData\Local\Programs\Python\Python311\Lib\site-packages\peewee.py", line 3441, in create_tables model.create_table(**options) File "C:\Users\Dell\AppData\Local\Programs\Python\Python311\Lib\site-packages\peewee.py", line 6943, in create_table if safe and not cls._schema.database.safe_create_index \ ^^^^^^^^^^^^^^^^^^^^ File "C:\Users\Dell\AppData\Local\Programs\Python\Python311\Lib\site-packages\peewee.py", line 5832, in database raise ImproperlyConfigured('database attribute does not appear to ' peewee.ImproperlyConfigured: database attribute does not appear to be set on the model: <Model: User>
The error you're encountering, peewee.ImproperlyConfigured: database attribute does not appear to be set on the model: <Model: User>, is due to the fact that you are trying to create tables using the create_tables function before setting the DATABASE variable to an instance of SqliteDatabase("test.db"). In your modified code, you are setting DATABASE to None initially, and then attempting to use it in the create_tables function before assigning it the SqliteDatabase instance.

To fix this issue, you need to set DATABASE to the SqliteDatabase("test.db") instance before calling the create_tables function. Here's the corrected code:

python
from peewee import *

# create a peewee database instance -- our models will use this database to
# persist information
DATABASE = None

def create_tables():
    with DATABASE as db:
        db.create_tables([User, Relationship, Message])

# model definitions -- the standard "pattern" is to define a base model class
# that specifies which database to use.  then, any subclasses will automatically
# use the correct storage.
class BaseModel(Model):
    class Meta:
        database = DATABASE

# the user model specifies its fields (or columns) declaratively, like django
class User(BaseModel):
    username = CharField(unique=True)
    password = CharField()
    email = CharField()
    join_date = DateTimeField()

# this model contains two foreign keys to user -- it essentially allows us to
# model a "many-to-many" relationship between users.  by querying and joining
# on different columns we can expose who a user is "related to" and who is
# "related to" a given user
class Relationship(BaseModel):
    from_user = ForeignKeyField(User, backref='relationships')
    to_user = ForeignKeyField(User, backref='related_to')

    class Meta:
        # `indexes` is a tuple of 2-tuples, where the 2-tuples are
        # a tuple of column names to index and a boolean indicating
        # whether the index is unique or not.
        indexes = (
            # Specify a unique multi-column index on from/to-user.
            (('from_user', 'to_user'), True),
        )

# a dead simple one-to-many relationship: one user has 0..n messages, exposed by
# the foreign key. a users messages will be accessible as a special attribute,
# User.messages.
class Message(BaseModel):
    user = ForeignKeyField(User, backref='messages')
    content = TextField()
    pub_date = DateTimeField()

if __name__ == "__main__":
    DATABASE = SqliteDatabase("test.db")
    create_tables()
Now, DATABASE is set to the SqliteDatabase("test.db") instance before calling create_tables(), which should resolve the issue you're facing.

link removed is a link to a top-notch learning platform.
(Dec-19-2023, 12:03 PM)khanzain Wrote: [ -> ]which should resolve the issue you're facing.
I don't see any changes between your code and OP second snippet