Assigning Meta.database dynamically

759 views
Skip to first unread message

Danny Gale

unread,
Mar 10, 2013, 8:32:43 PM3/10/13
to peewe...@googlegroups.com
Hello all,

I've used Django pretty extensively for some web-based projects so I'm used to the syntax and database interface they use -- which you seem to have duplicated almost perfectly. Well done! :)

Anyway, I'm now writing a piece of standalone software that needs to use a database to store information. The application creates a zip file as the "project file." That zip file contains some miscellaneous configuration and information stuff, as well as the database. Every project has its own project file and, as a result, its own database, so it can't just be hard-coded into the class.

What's the right way to do this within peewee?

Now, my first idea was to edit the Meta.database variable, but it doesn't exist! (What happens to the Meta subclass?)
>>> from peewee import *
>>> class MyModel(Model):
...     class Meta:
...             database = SqliteDatabase(None)
... 
>>> mm = MyModel()
>>> mm.Meta.database
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyModel' object has no attribute 'Meta'
>>> 

My second thought was to assign the Meta database variable to a member variable of the class:
>>> from peewee import *
>>> class MyModel(Model):
...     db = SqliteDatabase(None)
...     class Meta:
...             database = self.db
... 
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in MyModel
  File "<stdin>", line 4, in Meta
NameError: name 'self' is not defined

And now where I'm at, is looking at the MyModel class:
>>> class MyModel(Model):
...     class Meta:
...             database = SqliteDatabase(None)
... 
>>> dir(MyModel)
['DoesNotExist', '__class__', '__delattr__', '__dict__', '__doc__', '__eq__', '__format__', '__getattribute__', '__hash__', '__init__', '__metaclass__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_data', '_meta', '_prune_fields', 'alias', 'create', 'create_table', 'delete', 'delete_instance', 'dependencies', 'drop_table', 'filter', 'get', 'get_id', 'get_or_create', 'id', 'insert', 'prepared', 'raw', 'save', 'select', 'set_id', 'table_exists', 'update']
>>> 

Oh, look -- a meta class:
>>> dir(MyModel._meta)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'auto_increment', 'columns', 'database', 'db_table', 'defaults', 'fields', 'get_default_dict', 'get_field_names', 'get_fields', 'get_sorted_fields', 'indexes', 'model_class', 'name', 'order_by', 'prepared', 'primary_key', 'rel', 'rel_exists', 'rel_for_model', 'reverse_rel', 'reverse_rel_for_model']
>>> 

Oh, look -- a database!
>>> dir (mm._meta.database)
['_Database__local', '__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__hash__', '__init__', '__module__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_close', '_conn_lock', '_connect', 'autocommit', 'begin', 'close', 'commit', 'commit_on_success', 'commit_select', 'compiler', 'compiler_class', 'connect', 'connect_kwargs', 'create_foreign_key', 'create_index', 'create_sequence', 'create_table', 'database', 'deferred', 'drop_sequence', 'drop_table', 'empty_limit', 'execute_sql', 'field_overrides', 'for_update', 'get_autocommit', 'get_conn', 'get_cursor', 'get_indexes_for_table', 'get_tables', 'init', 'interpolation', 'is_closed', 'last_insert_id', 'op_overrides', 'quote_char', 'register_fields', 'register_ops', 'reserved_tables', 'rollback', 'rows_affected', 'sequence_exists', 'sequences', 'set_autocommit', 'subquery_delete_same_table', 'transaction']

So I assume mm._meta.database.database is the SqliteDatabase object that the model connects to.

What I want to know is -- will directly changing the MyModel._meta.database.database variable break anything and is there a more "proper" way to do this?

Charles

unread,
Mar 10, 2013, 8:49:01 PM3/10/13
to peewe...@googlegroups.com
Hi, thanks for your note.

The information you're looking for is here:

http://peewee.readthedocs.org/en/latest/peewee/api.html#Database.init

You can "defer" initializing your db if you get those values at runtime.  Let me know if you run into issues.

Danny Gale

unread,
Mar 10, 2013, 9:08:21 PM3/10/13
to peewe...@googlegroups.com
I'm familiar with deferring database initialization, but I don't think it's the right solution here. 

I guess a different way to say it is that I need to be able to assign some instances of a given model to one database, and some to another

Vadim Denisov

unread,
Jun 21, 2013, 6:20:50 AM6/21/13
to peewe...@googlegroups.com
Hi Danny,

I have a similar problem. Have you eventually found the solution?

понедельник, 11 марта 2013 г., 2:08:21 UTC+1 пользователь Danny Gale написал:

Stanislav Ivochkin

unread,
Dec 12, 2015, 11:41:30 AM12/12/15
to peewee-orm, vadimm...@gmail.com
A solution can be found in the latest peewee documentation - http://docs.peewee-orm.com/en/latest/peewee/database.html#using-multiple-databases

пятница, 21 июня 2013 г., 13:20:50 UTC+3 пользователь Vadim Denisov написал:
Reply all
Reply to author
Forward
0 new messages