Package: savannah
ORMTheormpackage is an async ORM for Python, with support for Postgres,
MySQL, and SQLite. ORM is built with:SQLAlchemy corefor query building.databasesfor cross-database async support.typesystemfor data validation.Because ORM is built on SQLAlchemy core, you can use Alembic to provide
database migrations.ORM is still under development: We recommend pinning any dependencies withorm~=0.1Note: Useipythonto try this from the console, since it supportsawait.importdatabasesimportormimportsqlalchemydatabase=databases.Database("sqlite:///db.sqlite")metadata=sqlalchemy.MetaData()classNote(orm.Model):__tablename__="notes"__database__=database__metadata__=metadataid=orm.Integer(primary_key=True)text=orm.String(max_length=100)completed=orm.Boolean(default=False)# Create the databaseengine=sqlalchemy.create_engine(str(database.url))metadata.create_all(engine)# .create()awaitNote.objects.create(text="Buy the groceries.",completed=False)awaitNote.objects.create(text="Call Mum.",completed=True)awaitNote.objects.create(text="Send invoices.",completed=True)# .all()notes=awaitNote.objects.all()# .filter()notes=awaitNote.objects.filter(completed=True).all()# exact, iexact, contains, icontains, lt, lte, gt, gte, innotes=awaitNote.objects.filter(text__icontains="mum").all()# .get()note=awaitNote.objects.get(id=1)# .update()awaitnote.update(completed=True)# .delete()awaitnote.delete()# 'pk' always refers to the primary keynote=awaitNote.objects.get(pk=2)note.pk# 2ORM supports loading and filtering across foreign keys...importdatabasesimportormimportsqlalchemydatabase=databases.Database("sqlite:///db.sqlite")metadata=sqlalchemy.MetaData()classAlbum(orm.Model):__tablename__="album"__metadata__=metadata__database__=databaseid=orm.Integer(primary_key=True)name=orm.String(max_length=100)classTrack(orm.Model):__tablename__="track"__metadata__=metadata__database__=databaseid=orm.Integer(primary_key=True)album=orm.ForeignKey(Album)title=orm.String(max_length=100)position=orm.Integer()# Create some records to work with.malibu=awaitAlbum.objects.create(name="Malibu")awaitTrack.objects.create(album=malibu,title="The Bird",position=1)awaitTrack.objects.create(album=malibu,title="Heart don't stand a chance",position=2)awaitTrack.objects.create(album=malibu,title="The Waters",position=3)fantasies=awaitAlbum.objects.create(name="Fantasies")awaitTrack.objects.create(album=fantasies,title="Help I'm Alive",position=1)awaitTrack.objects.create(album=fantasies,title="Sick Muse",position=2)# Fetch an instance, without loading a foreign key relationship on it.track=awaitTrack.objects.get(title="The Bird")# We have an album instance, but it only has the primary key populatedprint(track.album)# Album(id=1) [sparse]print(track.album.pk)# 1print(track.album.name)# Raises AttributeError# Load the relationship from the databaseawaittrack.album.load()asserttrack.album.name=="Malibu"# This time, fetch an instance, loading the foreign key relationship.track=awaitTrack.objects.select_related("album").get(title="The Bird")asserttrack.album.name=="Malibu"# Fetch instances, with a filter across an FK relationship.tracks=Track.objects.filter(album__name="Fantasies")assertlen(tracks)==2# Fetch instances, with a filter and operator across an FK relationship.tracks=Track.objects.filter(album__name__iexact="fantasies")assertlen(tracks)==2# Limit a querytracks=awaitTrack.objects.limit(1).all()assertlen(tracks)==1Data typesThe following keyword arguments are supported on all field types.primary_keyallow_nulldefaultindexuniqueAll fields are required unless one of the following is set:allow_null- Creates a nullable column. Sets the default toNone.allow_blank- Allow empty strings to validate. Sets the default to"".default- Set a default value for the field.The following column types are supported.
See TypeSystem fortype-specific validation keyword arguments.orm.String(max_length)orm.Text()orm.Boolean()orm.Integer()orm.Float()orm.Date()orm.Time()orm.DateTime()orm.JSON()