Tina4

Tina4-Python ORM#

๐Ÿ”ฅ Hot Tips

  • You never need the ORM. Raw Database is perfect for 90% of cases
  • But when you want it... it feels like writing plain Python classes
  • Zero boilerplate: no __init__, no save() method to write
  • Works with SQLite, PostgreSQL, MySQL, MSSQL, Firebird, all the same
:::

Quick Start - 8 lines {#quick-start}#

python
from tina4_python import ORM, orm, Databasefrom tina4_python import IntegerField, StringField, DateTimeFieldโ€‹class User(ORM):    id         = IntegerField(primary_key=True, auto_increment=True)    name       = StringField()    email      = StringField(unique=True)    created_at = DateTimeField()โ€‹# Connect once (usually in your main.py)orm(Database("sqlite3:test.db"))โ€‹# That's it - table is auto-created on first useuser = User({"name": "Alice", "email": "alice@example.com"})user.save()                    # โ†’ INSERTprint(user.id)                 # โ†’ 1โ€‹user.name = "Alice Wonder"user.save()                    # โ†’ UPDATEโ€‹user = User()user.load("email = ?", ["alice@example.com"])print(user.name)               # โ†’ Alice Wonder

Field Types {#field-types}#

Field TypePython typeSQL exampleNotes
IntegerField()intINTEGER
StringField()strVARCHAR(255)length=500 optional
TextField()strTEXTunlimited
DateTimeField()datetimeTIMESTAMP
NumericField()DecimalNUMERIC(10,2)
BlobField()bytesBLOB
JSONBField()dict/listJSON / JSONBauto serialize/deserialize
ForeignKeyField(...)intINTEGER REFERENCES table(id)import from tina4_python.FieldTypes

Field Options#

python
name = StringField(    default="Anonymous",    null=False,    length=100)created_at = DateTimeField()status = IntegerField(default=1)

Foreign Keys - Beautiful & Simple {#foreign-keys}#

python
from tina4_python.FieldTypes import ForeignKeyFieldโ€‹class Post(ORM):    id        = IntegerField(primary_key=True, auto_increment=True)    title     = StringField()    author_id = ForeignKeyField(references=User)

Usage:

python
post = Post({"title": "Hello World", "author_id": 1})post.save()โ€‹# Loadpost = Post()post.load("id = ?", [1])print(post.title)

Core Methods {#core-methods}#

MethodExampleWhat it doesReturns
.save()user.save()INSERT or UPDATE
.load(where, params)user.load("id = ?", [1])Load single record into instancebool
.select() / .fetch()User().select()Returns records (default limit 10)DatabaseResult
.fetch_one()User().fetch_one()Fetches one recordDatabaseResult
.delete()user.delete()Delete record
.create_table()User().create_table()Auto-create table
.to_dict()user.to_dict()Convert instance to dictdict

Migrations - One command {#migrations}#

python
from tina4_python.Migration import migrateโ€‹migrate(Database("sqlite3:test.db"))  # creates/updates all ORM tables

Full Example - Real Project Ready {#full-example}#

python
from tina4_python import ORM, orm, Databasefrom tina4_python import IntegerField, StringField, TextField, DateTimeFieldfrom tina4_python.FieldTypes import ForeignKeyFieldโ€‹orm(Database("sqlite3:app.db"))  # โ† one line to rule them allโ€‹class Category(ORM):    id   = IntegerField(primary_key=True, auto_increment=True)    name = StringField(unique=True)โ€‹class Article(ORM):    id          = IntegerField(primary_key=True, auto_increment=True)    title       = StringField()    content     = TextField()    category_id = ForeignKeyField(references=Category)    created_at  = DateTimeField()โ€‹# Auto-create tablesCategory().create_table()Article().create_table()โ€‹# Use itcat = Category({"name": "Tech"})cat.save()โ€‹article = Article({"title": "Tina4 is awesome", "content": "Great framework", "category_id": 1})article.save()โ€‹# Queryresult = Article().select(filter="category_id = ?", params=[1])for a in result.records:    print(a["title"])

Summary - The Tina4 ORM Philosophy {#summary}#

  • No __init__ needed
  • No save() method to write
  • No migration files
  • No sessions
  • No query builder hell

Just:

python
user = User({"name": "Bob"})user.save()โ€‹@post("/api/users")async def post_api_users(request, response):    user = User(request.body)    user.save()    return response(user.to_dict())