Expérience dans la création d'une application Web avec Pony ORM

Bonjour, Habr!


Récemment, j'ai eu la tâche d'écrire une application Web Python en Python pour partager une facture de restaurant entre les participants d'un repas. Comme nous avons besoin d'une base de données pour stocker des données sur les commandes et les utilisateurs, la question s'est posée de choisir ORM pour travailler avec la base de données. Le développement a été réalisé sur Flask, donc Django ORM a été immédiatement balayé et le choix s'est d'abord porté sur SQLAlchemy. D'une part, cet ORM est presque omnipotent, mais pour cette raison, il est assez difficile à maîtriser. Après avoir souffert d'alchimie pendant un certain temps, j'ai décidé de trouver une option plus simple pour accélérer le développement. En conséquence, Pony ORM a été choisi pour le projet.
image


, , . .


, . , , .


PonyORM:


  • ( lambda )

( )


, , Pony , , .


Pony , .



pip Pony:


pip install pony

DB API :


  • PostgreSQL: psycopg psycopg2cffi
  • Oracle: cx_Oracle
  • MySQL: PyMySQL

Pony:


from pony.orm import *


— . .


db = Database()

. Database db.bind() . . SQLite ( ) PostgreSQL (). , Database. :


settings = dict(
    sqlite=dict(provider='sqlite', filename='pony.db', create_db=True),
    postgres=dict(provider='postgres', user='pony', password='pony', host='localhost', 
        database='pony')
)

:


db = Database(**settings['postgres'])


ER . , Python . , .


image


:


from datetime import datetime
from pony.orm import *

db = Database()

class User(db.Entity):
    id = PrimaryKey(int, auto=True)
    fullname = Optional(str)
    password = Optional(str)
    nickname = Optional(str)
    lended = Set('Credit', reverse='lender')
    borrowed = Set('Credit', reverse='borrower')
    credit_editions = Set('CreditEdition', reverse='user')
    sessions = Set('UserInSession')
    affected_editions = Set('CreditEdition', reverse='affected_user')

class Session(db.Entity):
    id = PrimaryKey(int, auto=True)
    title = Optional(str)
    start = Optional(datetime)
    end = Optional(datetime)
    ordereders = Set('OrderedItem')
    users = Set('UserInSession')

class OrderedItem(db.Entity):
    id = PrimaryKey(int, auto=True)
    session = Required(Session)
    title = Optional(str)
    price = Optional(int)
    user_in_sessions = Set('UserInSession')

class Credit(db.Entity):
    id = PrimaryKey(int, auto=True)
    lender = Required(User, reverse='lended')
    borrower = Required(User, reverse='borrowed')
    value = Optional(int)
    credit_editions = Set('CreditEdition')

class UserInSession(db.Entity):
    id = PrimaryKey(int, auto=True)
    user = Required(User)
    session = Required(Session)
    orders = Set(OrderedItem)
    value = Optional(int)

class CreditEdition(db.Entity):
    id = PrimaryKey(int, auto=True)
    user = Required(User, reverse='credit_editions')
    affected_user = Required(User, reverse='affected_editions')
    credit = Required(Credit)
    old_value = Optional(int)
    new_value = Optional(int)

db.generate_mapping()

, , .



( ). :


session = Session[sid]

Session , id == sid.


De plus, comme je l'ai dit ci-dessus, les requêtes dans Pony peuvent être écrites dans des expressions de générateur, ce qui les rend beaucoup plus pratiques qu'en alchimie.
Voici un exemple dans lequel la base de données reçoit une demande de sélection d'utilisateurs qui participent à cette session et qui ne sont pas des utilisateurs virtuels.


users = select(u for u in User if u not in session.users.user and not u.virtual)

Conclusion


J'espère que mon article a été utile à quelqu'un. Si vous êtes également intéressé par Pony, je laisserai ci-dessous des liens vers la documentation et le canal télégramme de la communauté.


Merci pour l'attention!


Documentation de la communauté Pony
Telegram

Source: https://habr.com/ru/post/undefined/


All Articles