def test_attrib_nullables(): "Create nullable attributes that should get None as value" attr = Attribute('attr1', int, nullable=True) assert attr.value is None attr = Attribute('attr2', int, 0, nullable=True) assert attr.value is None attr = Attribute('attr3', str, '', nullable=True) assert attr.value is None attr = Attribute('attr4', date, nullable=True) assert attr.value is None
def tuple(self, *args, **kwargs): """Return a Tuple based on relvar and passed-in arguments :param args: positional arguments corresponding to attributes :param kwargs: keyword arguments corresponding to attributes :return: Tuple """ kwargs.update( dict(list(zip([name for name, attr in self.attributes], args)))) attribs = [] namelist = [] attrs = dict(self.attributes) for (argname, argval) in list(kwargs.items()): attr = attrs[argname] attribs.append( Attribute(argname, attr.type, argval, nullable=attr.nullable, sysdefault=attr.sysdefault)) namelist.append(argname) for name in self._required_attribs: if name not in namelist: raise ValueError("Missing required attribute: %s" % name) return Tuple(attribs)
def get_one(self, keytuple): """Execute a single-tuple retrieval and return the tuple data :param keytuple: Tuple with key values :return: Tuple or None """ attrdict = dict(self.attributes) attrnames = list(attrdict.keys()) def get_one_qry(): if not hasattr(self, 'get_one_qry'): from_clause = self.name self.get_one_qry = "SELECT %s.xmin, %s FROM %s %s" % ( self.name, ", ".join(attrnames), from_clause, self.where_clause()) return self.get_one_qry key = self.key_values(keytuple) row = self.db.fetchone(get_one_qry(), key) self.db.rollback() if not row: return None tup = Tuple([ Attribute(name, attrdict[name].type, row[name], nullable=attrdict[name].nullable, sysdefault=attrdict[name].sysdefault) for name in attrnames ]) tup._tuple_version = row['xmin'] return tup
def insert_one(self, newtuple, retkey=False): """Execute a single-tuple INSERT command :param newtuple: the tuple to be inserted :param retkey: indicates assigned key values should be returned """ attrnames = [name for name, typ in newtuple._heading] targets = '(%s)' % ", ".join(attrnames) values_list = 'VALUES (%s)' % ", ".join( ['%%(%s)s' % name for name in attrnames]) cmd = "INSERT INTO %s %s %s" % (self.name, targets, values_list) if retkey: cmd += " RETURNING %s" % ", ".join(self.key) curs = self.db.execute(cmd, tuple_values_dict(newtuple)) if curs.rowcount != 1: self.db.rollback() raise DatabaseError("Failed to add %s %r" % (self.extname, self)) if retkey: attrdict = dict(self.attributes) rettuple = Tuple( [Attribute(name, attrdict[name].type) for name in self.key]) row = curs.fetchone() for attr, type_ in rettuple._heading: setattr(rettuple, attr, row[attr]) curs.close() if retkey: return rettuple
def test_attrib_defaults(): "Create an attribute with default arguments" attr = Attribute('attr1') assert attr.name == 'attr1' assert attr.type == str assert attr.value == '' assert attr.nullable is False assert attr.sysdefault is False
def test_attrib_args(): "Create an attribute with various arguments" attr = Attribute('attr1', float, 45.67, sysdefault=True) assert attr.name == 'attr1' assert attr.type == float assert attr.value == 45.67 assert attr.nullable is False assert attr.sysdefault is True assert repr(attr) == "Attribute(attr1 float)"
def key_tuple(self, *args, **kwargs): """Return a Tuple of key attributes, with given values :param args: positional arguments corresponding to key attributes :param kwargs: keyword arguments corresponding to key attributes :return: Tuple """ kwargs.update(dict(list(zip(self.key, args)))) return Tuple([ Attribute(name, type(val), val) for name, val in list(kwargs.items()) ])
def default_tuple(self): """Return a Tuple of key and required attributes, with default values :return: Tuple """ attrs = self.key[:] attrs.extend( [name for name in self._required_attribs if not name in attrs]) return Tuple([ Attribute(name, attr.type) for name, attr in self.attributes if name in attrs ])
from copy import copy from datetime import date, datetime, timedelta import pytest from psycopg2 import DatabaseError, IntegrityError from pyrseas.relation import RelVar, Attribute from pyrseas.testutils import RelationTestCase TEST_DATA1 = {'title': "John Doe"} TEST_DATA1x = {'id': 2, 'title': "Bob Smith"} TEST_DATA2 = {'num': 123, 'name': "Name 1", 'id': 1} TEST_DATA3 = {'id1': 1, 'id2': 2, 'code': 'ES', 'descr': 'Una descripción'} rv1 = RelVar('rv1', [Attribute('id', int, sysdefault=True), Attribute('title'), Attribute('descr', nullable=True), Attribute('updated', datetime, sysdefault=True)], key=['id']) rv2 = RelVar('rv2', [Attribute('num', int), Attribute('name'), Attribute('id', int)], key=['num']) rv3 = RelVar('rv3', [Attribute('id1', int), Attribute('id2', int), Attribute('code'), Attribute('descr'), Attribute('created', date, sysdefault=True)], key=['id1', 'code', 'id2']) @pytest.fixture
def test_attrib_unicode_is_str(): "Accept str as type synonym for unicode under Python 2" val = unicode('A string') attr = Attribute('attr1', value=val) assert attr.type == str assert attr.value == val
def test_attrib_int_is_float(): "Accept an int value for float type" attr = Attribute('attr1', float, 0) assert attr.type == float assert attr.value == 0.0
def test_attrib_not_nullable_sysdefault(): "Allow non-nullable, system-defaultable attribute to be None" attr = Attribute('attr1', date, sysdefault=True) assert attr.value is None
def test_attrib_not_nullable_no_value(): "Ensure non-nullable, non-defaultable attribute has a value" with pytest.raises(ValueError): Attribute('attr1', date)
def test_attrib_nullable_value_error(): "Validate declared type against value type for a nullable attribute" with pytest.raises(ValueError): Attribute('attr1', str, 123, nullable=True)
def test_attrib_value_error(): "Validate declared type against value type" with pytest.raises(ValueError): Attribute('attr1', int, 12.34)
# -*- coding: utf-8 -*- from pyrseas.relation import Attribute, RelVar from pyrseas.relation import ProjAttribute, Projection, JoinRelation Film_RV = RelVar('film', [ Attribute('id', int, sysdefault=True), Attribute('title'), Attribute('release_year', int) ], key=['id']) Film_List = JoinRelation([ Projection('film', [ ProjAttribute('id', int), ProjAttribute('title'), ProjAttribute('release_year', int) ]) ])
# -*- coding: utf-8 -*- from pyrseas.relation import Attribute, RelVar from pyrseas.relation import ProjAttribute, Projection, JoinRelation def film_repr(tup): return "%s - %d" % (tup.title, tup.release_year) Film_RV = RelVar('film', [ Attribute('id', int), Attribute('title'), Attribute('release_year', int)], key=['id']) Film_List = JoinRelation([ Projection('film', [ProjAttribute('id', int), ProjAttribute('title'), ProjAttribute('release_year', int)])])
def test_attrib_value(): "Create an attribute with a given value" attr = Attribute('attr1', int, 123) assert attr.type == int assert attr.value == 123