Home » Beitrag verschlagwortet mit 'ORM'
Schlagwort-Archive: ORM
SQLAlchemy/Python DB-Manipulation basierend of ORM Model
Wenn z.B. ein Python File vorliegt, dass DB-Connectivity und Entitätenmodell definiert:
(Python interpreter wurde aus dem Verzeichnis mit dem app.py gestartet. FLASK_APP Environmentvariable zeigte auch auf das app.py File.)
app = Flask(__name__)
app.config['SQLALCHEMY_DATABASE_URI'] = 'postgresql://postgres:admin@localhost:5432/todoDB'
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db = SQLAlchemy(app)
class TodoList(db.Model):
__tablename__ = 'todolists'
id = db.Column(db.Integer, primary_key=True)
name = db.Column(db.String(), nullable=False)
todos = db.relationship('Todo', backref='list', lazy=True)
def __repr__(self):
return f'<TodoList {self.id} {self.name}>'
class Todo(db.Model):
__tablename__ = 'todos'
id = db.Column(db.Integer, primary_key=True)
description = db.Column(db.String(), nullable=False)
completed = db.Column(db.Boolean, nullable=False, default=False)
list_id = db.Column(db.Integer, db.ForeignKey('todolists.id'), nullable=False)
def __repr__(self):
return f'<Todo {self.id} {self.description}, list {self.list_id}>'
Beachte: Der Foreign Key heisst ‚list_id‚, die ‚backref‘ wird aber mit ‚list‚ angegeben und auch das TodoList-Parent-Objekt wird (siehe unten) an die Referenz Todo.list angehängt.
Dann können mittels Python auf der Commandline folgendermassen Entitäten erstellt und gespeichert werden:
C:\tmp\Python_Workspace1\step4-todoapp-crud-lists>python
Python 3.7.9 (tags/v3.7.9:13c94747c7, Aug 17 2020, 16:30:00) [MSC v.1900 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from app import db, Todo, TodoList
>>> list1 = TodoList(name='Haushalt')
>>> todo1 = Todo(description='putzen')
>>> todo2 = Todo(description='kochen')
>>> todo1.list=list1
>>> todo2.list=list1
>>> list1.id=3
>>> db.session.add(list1)
>>> db.session.commit()
Resultat:
todoDB=# select * from todos;
id | description | completed | list_id
----+-------------+-----------+---------
6 | putzen | f | 3
7 | kochen | f | 3
(5 Zeilen)
todoDB=# select * from todolists;
id | name
----+---------------
3 | Haushalt
(3 Zeilen)
todoDB=#
Define ORM in SQLAlchemy
References
- Flask-SQLAlchemy – Simple Relationships
- SQLAlchemy Docs: Relationship API
- the SQLAlchemy Docs on Relationship Loading Techniques
- SQLALchemy ORM Relationship Docs
- SQLAlchemy Docs on Defining Constraints
Define a Parent-Child Relationship
class Driver(db.Model):
__tablename__ = 'drivers'
id = db.Column(db.Integer, privary_key=True)
...
vehicles = db.relationship('Vehicle', backref='driver' , lazy=True)
class Vehicle(db.Model):
__tablename__ = 'vehicles'
id = db.Column(db.Integer, privary_key=True)
...
driver_id = db.Column(db.Integer, db.ForeignKey('drivers.id'), nullable=False)
Beachte: Die backref heisst driver, das der relevante Foreign Key jedoch driver_id!
Erklärungen
Option: | Erklärung: |
---|---|
lazy=True (default) | lazy loading |
lazy=’select‘ | eager loading |
db.ForeignKey(‚drivers.id) | 1. ACHTUNG: Tabellennamen benutzen, nicht den Entity-Namen (‚drivers.id‚, nicht ‚Driver.id‘)! 2. Datentypen von FK und dessen Ziel müssen übereinstimmen. |
Weitere relationship Konfig-Optionen: collection_class = … cascade = … See: SQLALchemy ORM Relationship Docs | Beispiele: collection_class = list cascade = ’save-update‘ # OR: all, delete-orphan |