Utilizzo degli ORM in due programmi separati che condividono un DB

2

Ho un'applicazione divisa in due parti principali:

  1. Un web crawler scritto in Python
  2. Un'API REST scritta in Golang

Condividono un database MySQL, che viene principalmente popolato / aggiornato dal crawler web e quindi letto dall'API REST.

Volevo utilizzare un ORM su ciascun lato per facilitare l'interazione con il database, ma ora non sono sicuro che sia un buon approccio.

Sul lato Python, stavo cercando di usare peewee , e per Golang userò gorm .

Non sembra una buona idea mantenere due serie di file modello ORM, dove dovrei cambiare ogni set ogni volta che voglio modificare alcuni attributi del database. Inoltre, sono preoccupato che con due ORM in lotta per la struttura del database, che potrebbero sorgere conflitti, o che i modelli potrebbero non essere sincronizzati con ciò che è la struttura db effettiva.

Questo è uno scenario in cui l'utilizzo di un ORM causerà più problemi del suo valore? O forse dovrei usare un singolo ORM (per Python o Golang) e scrivere query non elaborate per l'altro lato.

    
posta TylerAndFriends 13.10.2015 - 06:14
fonte

2 risposte

2

Penso che sia giusto avere due serie di ORM se pensi che ti semplificherà la vita in termini di creazione delle applicazioni. Pensateci in questo modo senza l'ORM e avrete bisogno di cambiare le query in entrambe le applicazioni se apportate alcune modifiche allo schema del database, ecc. Quindi non ritengo che sia un grosso problema. Per quanto tu possa guadagnare produttività usando ORM su entrambe le applicazioni, dovrebbe andar bene.

    
risposta data 13.10.2015 - 07:30
fonte
0

Usa entrambi e scrivi uno script Python per importare i modelli peewee e convertirli in modelli GORM.

Ho graffiato qualcosa di molto semplice. Ho creato models.py con l'esempio in README.md di peewee:

from peewee import *
import datetime

db = SqliteDatabase('my_database.db', threadlocals=True)

class BaseModel(Model):
    class Meta:
        database = db

class User(BaseModel):
    username = CharField(unique=True)

class Tweet(BaseModel):
    user = ForeignKeyField(User, related_name='tweets')
    message = TextField()
    created_date = DateTimeField(default=datetime.datetime.now)
    is_published = BooleanField(default=True)

Ed ecco un semplice script che lo importa e crea il codice Go:

import peewee

def enumerate_models():
    import models
    for name in dir(models):
        item = getattr(models, name)
        if isinstance(item, type) and issubclass(item, models.BaseModel) and item != models.BaseModel:
            yield item


def model_fields(model):
    for name in dir(model):
        item = getattr(model, name)
        if isinstance(item, peewee.Field):
            yield name, item


def field_go_type(field_spec):
    return {
        peewee.PrimaryKeyField: 'uint',
        peewee.ForeignKeyField: 'uint',
        peewee.TextField: 'string',
        peewee.CharField: 'string',
        peewee.DateTimeField: 'time.Time',
        peewee.BooleanField: 'bool',
    }.get(type(field_spec), '?%s?' % type(field_spec))


for model in enumerate_models():
    print('type' ,model.__name__, 'struct {')
    for field_name, field_spec in model_fields(model):
        field_go_decleration = []
        field_go_decleration.append(field_name)
        field_go_decleration.append(field_go_type(field_spec))
        print('\t' + ' '.join(field_go_decleration))
    print('}')

È in uscita:

type Tweet struct {
    created_date time.Time
    id uint
    is_published bool
    message string
    user uint
}
type User struct {
    id uint
    username string
}

Il mio script ha ancora bisogno di più lavoro per aggiungere le annotazioni, ma ottieni l'idea di base.

    
risposta data 13.10.2015 - 12:40
fonte

Leggi altre domande sui tag