pwiz, a model generator

pwiz is a little script that ships with peewee and is capable of introspecting an existing database and generating model code suitable for interacting with the underlying data. If you have a database already, pwiz can give you a nice boost by generating skeleton code with correct column affinities and foreign keys.

If you install peewee using setup.py install, pwiz will be installed as a “script” and you can just run:

  1. python -m pwiz -e postgresql -u postgres my_postgres_db

This will print a bunch of models to standard output. So you can do this:

  1. python -m pwiz -e postgresql my_postgres_db > mymodels.py
  2. python # <-- fire up an interactive shell
  1. >>> from mymodels import Blog, Entry, Tag, Whatever
  2. >>> print [blog.name for blog in Blog.select()]

Command-line options

pwiz accepts the following command-line options:

OptionMeaningExample
-hshow help 
-edatabase backend-e mysql
-Hhost to connect to-H remote.db.server
-pport to connect on-p 9001
-udatabase user-u postgres
-Pdatabase password-P secret
-sschema-s public
-ttables to generate-t tweet,users,relationships
-vgenerate models for VIEWs(no argument)
-iadd info metadata to generated file(no argument)
-otable column order is preserved(no argument)

The following are valid parameters for the engine (-e):

  • sqlite
  • mysql
  • postgresql

pwiz examples

Examples of introspecting various databases:

  1. # Introspect a Sqlite database.
  2. python -m pwiz -e sqlite path/to/sqlite_database.db
  3. # Introspect a MySQL database, logging in as root:secret.
  4. python -m pwiz -e mysql -u root -P secret mysql_db_name
  5. # Introspect a Postgresql database on a remote server.
  6. python -m pwiz -e postgres -u postgres -H 10.1.0.3 pg_db_name

Full example:

  1. $ sqlite3 example.db << EOM
  2. CREATE TABLE "user" ("id" INTEGER NOT NULL PRIMARY KEY, "username" TEXT NOT NULL);
  3. CREATE TABLE "tweet" (
  4. "id" INTEGER NOT NULL PRIMARY KEY,
  5. "content" TEXT NOT NULL,
  6. "timestamp" DATETIME NOT NULL,
  7. "user_id" INTEGER NOT NULL,
  8. FOREIGN KEY ("user_id") REFERENCES "user" ("id"));
  9. CREATE UNIQUE INDEX "user_username" ON "user" ("username");
  10. EOM
  11. $ python -m pwiz -e sqlite example.db

Produces the following output:

  1. from peewee import *
  2. database = SqliteDatabase('example.db', **{})
  3. class UnknownField(object):
  4. def __init__(self, *_, **__): pass
  5. class BaseModel(Model):
  6. class Meta:
  7. database = database
  8. class User(BaseModel):
  9. username = TextField(unique=True)
  10. class Meta:
  11. table_name = 'user'
  12. class Tweet(BaseModel):
  13. content = TextField()
  14. timestamp = DateTimeField()
  15. user = ForeignKeyField(column_name='user_id', field='id', model=User)
  16. class Meta:
  17. table_name = 'tweet'

Observations:

  • The foreign-key Tweet.user_id is detected and mapped correctly.
  • The User.username UNIQUE constraint is detected.
  • Each model explicitly declares its table name, even in cases where it is not necessary (as Peewee would automatically translate the class name into the appropriate table name).
  • All the parameters of the ForeignKeyField are explicitly declared, even though they follow the conventions Peewee uses by default.

Note

The UnknownField is a placeholder that is used in the event your schema contains a column declaration that Peewee doesn’t know how to map to a field class.