Je suis nouveau à SQLAlchemy (et SQL, d'ailleurs). Je n'arrive pas à comprendre comment coder l'idée que j'ai dans ma tête. Je crée une base de données de résultats de tests de performance.Comment coder cette relation dans SQLAlchemy?
Un essai se compose d'un type de test et un certain nombre (ce qui est classe TestRun ci-dessous)
Une suite de test se compose la chaîne de version du logiciel testé, et un ou plusieurs objets TestRun (ce qui est classe TestSuite au dessous de).
Une version de test est constituée de toutes les suites de tests avec le nom de version donné.
Voici mon code, aussi simple que je peux le faire:
from sqlalchemy import *
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, backref, sessionmaker
Base = declarative_base()
class TestVersion (Base):
__tablename__ = 'versions'
id = Column (Integer, primary_key=True)
version_name = Column (String)
def __init__ (self, version_name):
self.version_name = version_name
class TestRun (Base):
__tablename__ = 'runs'
id = Column (Integer, primary_key=True)
suite_directory = Column (String, ForeignKey ('suites.directory'))
suite = relationship ('TestSuite', backref=backref ('runs', order_by=id))
test_type = Column (String)
rate = Column (Integer)
def __init__ (self, test_type, rate):
self.test_type = test_type
self.rate = rate
class TestSuite (Base):
__tablename__ = 'suites'
directory = Column (String, primary_key=True)
version_id = Column (Integer, ForeignKey ('versions.id'))
version_ref = relationship ('TestVersion', backref=backref ('suites', order_by=directory))
version_name = Column (String)
def __init__ (self, directory, version_name):
self.directory = directory
self.version_name = version_name
# Create a v1.0 suite
suite1 = TestSuite ('dir1', 'v1.0')
suite1.runs.append (TestRun ('test1', 100))
suite1.runs.append (TestRun ('test2', 200))
# Create a another v1.0 suite
suite2 = TestSuite ('dir2', 'v1.0')
suite2.runs.append (TestRun ('test1', 101))
suite2.runs.append (TestRun ('test2', 201))
# Create another suite
suite3 = TestSuite ('dir3', 'v2.0')
suite3.runs.append (TestRun ('test1', 102))
suite3.runs.append (TestRun ('test2', 202))
# Create the in-memory database
engine = create_engine ('sqlite://')
Session = sessionmaker (bind=engine)
session = Session()
Base.metadata.create_all (engine)
# Add the suites in
version1 = TestVersion (suite1.version_name)
version1.suites.append (suite1)
session.add (suite1)
version2 = TestVersion (suite2.version_name)
version2.suites.append (suite2)
session.add (suite2)
version3 = TestVersion (suite3.version_name)
version3.suites.append (suite3)
session.add (suite3)
session.commit()
# Query the suites
for suite in session.query (TestSuite).order_by (TestSuite.directory):
print "\nSuite directory %s, version %s has %d test runs:" % (suite.directory, suite.version_name, len (suite.runs))
for run in suite.runs:
print " Test '%s', result %d" % (run.test_type, run.rate)
# Query the versions
for version in session.query (TestVersion).order_by (TestVersion.version_name):
print "\nVersion %s has %d test suites:" % (version.version_name, len (version.suites))
for suite in version.suites:
print " Suite directory %s, version %s has %d test runs:" % (suite.directory, suite.version_name, len (suite.runs))
for run in suite.runs:
print " Test '%s', result %d" % (run.test_type, run.rate)
La sortie de ce programme:
Suite directory dir1, version v1.0 has 2 test runs:
Test 'test1', result 100
Test 'test2', result 200
Suite directory dir2, version v1.0 has 2 test runs:
Test 'test1', result 101
Test 'test2', result 201
Suite directory dir3, version v2.0 has 2 test runs:
Test 'test1', result 102
Test 'test2', result 202
Version v1.0 has 1 test suites:
Suite directory dir1, version v1.0 has 2 test runs:
Test 'test1', result 100
Test 'test2', result 200
Version v1.0 has 1 test suites:
Suite directory dir2, version v1.0 has 2 test runs:
Test 'test1', result 101
Test 'test2', result 201
Version v2.0 has 1 test suites:
Suite directory dir3, version v2.0 has 2 test runs:
Test 'test1', result 102
Test 'test2', result 202
Ce n'est pas correct, car il y a deux objets Testversion avec le nom 'v1.0'. Je piraté mon chemin en ajoutant une liste privée d'objets Testversion, et une fonction de trouver un correspondant à un:
versions = []
def find_or_create_version (version_name):
# Find existing
for version in versions:
if version.version_name == version_name:
return (version)
# Create new
version = TestVersion (version_name)
versions.append (version)
return (version)
Je modifié mon code qui ajoute les enregistrements à utiliser:
# Add the suites in
version1 = find_or_create_version (suite1.version_name)
version1.suites.append (suite1)
session.add (suite1)
version2 = find_or_create_version (suite2.version_name)
version2.suites.append (suite2)
session.add (suite2)
version3 = find_or_create_version (suite3.version_name)
version3.suites.append (suite3)
session.add (suite3)
maintenant, la sortie est ce que je veux:
Suite directory dir1, version v1.0 has 2 test runs:
Test 'test1', result 100
Test 'test2', result 200
Suite directory dir2, version v1.0 has 2 test runs:
Test 'test1', result 101
Test 'test2', result 201
Suite directory dir3, version v2.0 has 2 test runs:
Test 'test1', result 102
Test 'test2', result 202
Version v1.0 has 2 test suites:
Suite directory dir1, version v1.0 has 2 test runs:
Test 'test1', result 100
Test 'test2', result 200
Suite directory dir2, version v1.0 has 2 test runs:
Test 'test1', result 101
Test 'test2', result 201
Version v2.0 has 1 test suites:
Suite directory dir3, version v2.0 has 2 test runs:
Test 'test1', result 102
Test 'test2', result 202
Cela se sent mal à moi; il ne me semble pas normal de garder une trace des noms de versions uniques et d'ajouter manuellement les suites aux objets TestVersion appropriés.
Ce code est-il proche d'être correct?
Et que se passe-t-il si je ne compile pas toute la base de données, comme dans cet exemple. Si la base de données existe déjà, dois-je interroger la table TestVersion de la base de données pour découvrir les noms de version uniques?
Merci d'avance. Je sais que c'est beaucoup de code à parcourir, et j'apprécie l'aide.
Je viens de parler à un collègue qui m'a mis au clair. Je ne veux pas du tout la table TestVersion; quand je veux connaître les noms de version uniques, j'ai besoin d'interroger la base de données; par exemple, "sélectionnez nom_version distinct des suites"; Quand je trouverai l'équivalent SQLAlchemy, je le signalerai. Merci encore. –
pour la valeur dans session.query (TestSuite.version_name) .distinct(): valeur d'impression –