def test_alter_column_default(self, registry): t = registry.migration.table('test') c = t.column('other').alter(server_default='test') if sgdb_in(['PostgreSQL']): assert c.server_default == "'test'::character varying" else: assert str(c.server_default) == "'test'"
class TestJsonRelated2: @pytest.fixture(autouse=True) def transact(self, request, registry_json_related2): transaction = registry_json_related2.begin_nested() request.addfinalizer(transaction.rollback) return def test_field_json_related_get_4(self, registry_json_related2): registry = registry_json_related2 t = registry.Test.insert(properties={'sub': {'name': 'jssuzanne'}}) assert t.name == 'jssuzanne' def test_field_json_related_del_2(self, registry_json_related2): registry = registry_json_related2 t = registry.Test.insert() del t.name assert t.name is None assert t.properties == {'sub': {'name': None}} def test_field_json_related_set_4(self, registry_json_related2): registry = registry_json_related2 t = registry.Test.insert(properties={'sub': {'name': 'other'}}) t.name = 'jssuzanne' assert t.properties == {'sub': {'name': 'jssuzanne'}} @pytest.mark.skipif(sgdb_in(['MariaDB', 'MsSQL']), reason='JSON is not existing in this SGDB') def test_field_json_related_exp_4(self, registry_json_related2): registry = registry_json_related2 Test = registry.Test Test.insert(properties={'sub': {'name': 'jssuzanne'}}) query = registry.Test.query().filter( Test.name.cast(types.String) == '"jssuzanne"') assert query.count()
class TestSimpleView: @pytest.fixture(autouse=True) def transact(self, request, registry_simple_view): transaction = registry_simple_view.begin_nested() request.addfinalizer(transaction.rollback) def test_has_a_mapper(self, registry_simple_view): registry = registry_simple_view assert registry.TestView.__mapper__ is not None def test_ok(self, registry_simple_view): registry = registry_simple_view TestView = registry.TestView v1 = TestView.query().filter(TestView.code == 'test1').first() v2 = TestView.query().filter(TestView.code == 'test2').first() assert v1.val1 == 1 assert v1.val2 == 2 assert v2.val1 == 3 assert v2.val2 == 4 @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="View must be in RO issue #95") def test_view_update_method(self, registry_simple_view): registry = registry_simple_view with pytest.raises(OperationalError): registry.TestView.query().update({'val2': 3}) def test_view_delete_method(self, registry_simple_view): registry = registry_simple_view with pytest.raises((OperationalError, ProgrammingError)): registry.TestView.query().delete()
def add_in_registry(): register = Declarations.register Model = Declarations.Model @register(Model) class Test: __db_schema__ = 'test_db_schema' integer = Int(primary_key=True) other = Str() @register(Model) class TestUnique: __db_schema__ = 'test_db_schema' integer = Int(primary_key=True) other = Str(unique=True) @register(Model) class TestIndex: __db_schema__ = 'test_db_schema' integer = Int(primary_key=True) other = Str(index=True) if not sgdb_in(['MySQL', 'MariaDB']): @register(Model) class TestCheck: __db_schema__ = 'test_db_schema' integer = Int(primary_key=True) @classmethod def define_table_args(cls): table_args = super(TestCheck, cls).define_table_args() return table_args + ( CheckConstraint('integer > 0', name='test'),) @register(Model) class TestFKTarget: __db_schema__ = 'test_db_schema' integer = Int(primary_key=True) @register(Model) class TestFK: __db_schema__ = 'test_db_schema' integer = Int(primary_key=True) other = Int( foreign_key=Model.TestFKTarget.use('integer')) @register(Model) class TestFK2: __db_schema__ = 'test_db_schema' integer = Int(primary_key=True) other = Int( foreign_key=Model.TestFKTarget.use('integer').options( ondelete='cascade'))
def reset_db(): if sgdb_in(['MySQL', 'MariaDB']): url = Configuration.get('get_url')() if database_exists(url): drop_database(url) db_template_name = Configuration.get('db_template_name', None) create_database(url, template=db_template_name)
def clean_db(request, configuration_loaded): def clean(): url = Configuration.get('get_url')() drop_database(url) db_template_name = Configuration.get('db_template_name', None) create_database(url, template=db_template_name) if sgdb_in(['MySQL', 'MariaDB']): clean() request.addfinalizer(clean)
def base_loaded(request, configuration_loaded): if sgdb_in(['MySQL', 'MariaDB']): return url = Configuration.get('get_url')() if not database_exists(url): db_template_name = Configuration.get('db_template_name', None) create_database(url, template=db_template_name) BlokManager.load() registry = init_registry_with_bloks([], None) registry.commit() registry.close() BlokManager.unload()
def test_drop_schema(self, registry): schema = registry.migration.schema('test_db_schema') schema.table('test').drop() schema.table('testfk').drop() schema.table('testunique').drop() schema.table('testfk2').drop() schema.table('testfktarget').drop() schema.table('testindex').drop() if not sgdb_in(['MySQL', 'MariaDB']): schema.table('testcheck').drop() schema.drop() with pytest.raises(MigrationException): registry.migration.schema('test_db_schema') # MySQL waiting that this schema exist for the next test registry.migration.schema().add('test_db_schema')
def test_detect_schema_added(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.TestFK.__table__.drop(bind=conn) registry.TestUnique.__table__.drop(bind=conn) registry.TestFK2.__table__.drop(bind=conn) registry.TestFKTarget.__table__.drop(bind=conn) registry.TestIndex.__table__.drop(bind=conn) if not sgdb_in(['MySQL', 'MariaDB']): registry.TestCheck.__table__.drop(bind=conn) conn.execute(DropSchema('test_db_schema')) report = registry.migration.detect_changed(schema_only=True) assert report.log_has("Add schema test_db_schema") report.apply_change() report = registry.migration.detect_changed(schema_only=True) assert not report.log_has("Add schema test_db_schema")
def test_detect_drop_column_with_foreign_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData(naming_convention=naming_convention) meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64), ForeignKey('system_blok.name')), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() message = ("Drop Foreign keys on test.other2 => %ssystem_blok.name" ) % ('dbo.' if sgdb_in(['MsSQL']) else '') assert report.log_has(message) report.apply_change() report = registry.migration.detect_changed() assert not report.log_has(message)
class TestMigration: def test_detect_column_added_with_protected_table(self, registry): # Remove a column on the table force the detection to found new column # which is existing in metadata but not in table with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True)) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has("Add test.other") def test_detect_column_added_with_protected_column(self, registry): # Remove a column on the table force the detection to found new column # which is existing in metadata but not in table with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True)) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': ['other']} report = registry.migration.detect_changed() assert report.log_has("Add test.other") def test_detect_column_removed(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has("Drop Column test.other2") def test_detect_nullable_with_protected_table(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), nullable=False), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has("Alter test.other") def test_detect_nullable_with_protected_column(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), nullable=False), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': ['other']} report = registry.migration.detect_changed() assert not report.log_has("Alter test.other") def test_detect_server_default_with_protected_table(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), server_default='9.99'), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has("Alter test.other") def test_detect_server_default_with_protected_column(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), server_default='9.99'), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': ['other']} report = registry.migration.detect_changed() assert not report.log_has("Alter test.other") def test_detect_drop_anyblok_index(self, registry): with cnx(registry) as conn: conn.execute( """CREATE INDEX anyblok_ix_test__other ON test (other);""") registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has("Drop index anyblok_ix_test__other on test") def test_detect_type_with_protected_table(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has("Alter test.other") def test_detect_type_with_protected_column(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': ['other']} report = registry.migration.detect_changed() assert not report.log_has("Alter test.other") def test_detect_add_foreign_key_with_protected_table(self, registry): with cnx(registry) as conn: registry.TestFK.__table__.drop(bind=conn) registry.TestFK.__table__ = Table( 'testfk', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), ) registry.TestFK.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'testfk': True} report = registry.migration.detect_changed() assert not report.log_has( "Add Foreign keys on (testfk.other) => (testfktarget.integer)") def test_detect_add_foreign_key_with_protected_column(self, registry): with cnx(registry) as conn: registry.TestFK.__table__.drop(bind=conn) registry.TestFK.__table__ = Table( 'testfk', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), ) registry.TestFK.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'testfk': ['other']} report = registry.migration.detect_changed() assert not report.log_has( "Add Foreign keys on (testfk.other) => (testfktarget.integer)") def test_detect_drop_foreign_key_with_protected_table(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData(naming_convention=naming_convention) meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64), ForeignKey('system_blok.name')), ) registry.Test.__table__.create(bind=conn) # anyblok_fk_test__other_on_system_blok__name registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has( "Drop Foreign keys on test.other => system_blok.name") def test_detect_drop_foreign_key_with_protected_column(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData(naming_convention=naming_convention) meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64), ForeignKey('system_blok.name')), ) registry.Test.__table__.create(bind=conn) # anyblok_fk_test__other_on_system_blok__name registry.migration.ignore_migration_for = {'test': ['other']} report = registry.migration.detect_changed() assert not report.log_has( "Drop Foreign keys on test.other => system_blok.name") @pytest.mark.skipif(sgdb_in(['MsSQL']), reason="MsSQL does not add unique #121") def test_detect_add_unique_constraint_with_protected_table(self, registry): with cnx(registry) as conn: registry.TestUnique.__table__.drop(bind=conn) registry.TestUnique.__table__ = Table( 'testunique', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), ) registry.TestUnique.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'testunique': True} report = registry.migration.detect_changed() assert not report.log_has( "Add unique constraint on testunique (other)") @pytest.mark.skipif(sgdb_in(['MsSQL']), reason="MsSQL does not add unique #121") def test_detect_add_unique_constraint_with_protected_column( self, registry): with cnx(registry) as conn: registry.TestUnique.__table__.drop(bind=conn) registry.TestUnique.__table__ = Table( 'testunique', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), ) registry.TestUnique.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'testunique': ['other']} report = registry.migration.detect_changed() assert not report.log_has( "Add unique constraint on testunique (other)") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="MySQL transform unique constraint on index") @pytest.mark.skipif(sgdb_in(['MsSQL']), reason="MsSQL does not drop unique #121") def test_detect_drop_unique_anyblok_constraint(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), Column('other', String(64), unique=True), ) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has( "Drop constraint anyblok_uq_test__other on test") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="No CheckConstraint works #90") def test_detect_add_check_constraint(self, registry): with cnx(registry) as conn: registry.TestCheck.__table__.drop(bind=conn) registry.TestCheck.__table__ = Table( 'testcheck', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), ) registry.TestCheck.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'testcheck': True} report = registry.migration.detect_changed() assert not report.log_has( "Add check constraint anyblok_ck_testcheck__test on testcheck") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="No CheckConstraint works #90") def test_detect_drop_check_anyblok_constraint(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), Column('other', String(64)), CheckConstraint("other != 'test'", name='check')) registry.Test.__table__.create(bind=conn) registry.migration.ignore_migration_for = {'test': True} report = registry.migration.detect_changed() assert not report.log_has( "Drop check constraint anyblok_ck__test__check on test")
view_with_relationship_on_self_2, ] ) def registry_view_with_relationship_on_self(request, bloks_loaded): reset_db() registry = init_registry_with_bloks( [], request.param) request.addfinalizer(registry.close) parent = registry.T1.insert(code='test1', val=1) registry.T2.insert(code='test1', val=2) registry.T1.insert(code='test2', val=3, parent=parent) registry.T2.insert(code='test2', val=4) return registry @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="No sub query") class TestViewWithRelationShipOnSelf: @pytest.fixture(autouse=True) def transact(self, request, registry_view_with_relationship_on_self): transaction = registry_view_with_relationship_on_self.begin_nested() request.addfinalizer(transaction.rollback) return def test_ok(self, registry_view_with_relationship_on_self): registry = registry_view_with_relationship_on_self TestView = registry.TestView v1 = TestView.query().filter(TestView.code == 'test1').first() v2 = TestView.query().filter(TestView.code == 'test2').first() assert v1.val1 == 1 assert v1.val2 == 2
class TestColumns: @pytest.fixture(autouse=True) def close_registry(self, request, bloks_loaded): def close(): if hasattr(self, 'registry'): self.registry.close() request.addfinalizer(close) def init_registry(self, *args, **kwargs): reset_db() self.registry = init_registry(*args, **kwargs) return self.registry def test_insert_columns(self, column_definition): column, value, kwargs = column_definition registry = self.init_registry(simple_column, ColumnType=column, **kwargs) test = registry.Test.insert(col=value) assert test.col == value def test_column_with_type_in_kwargs(self): self.init_registry( simple_column, ColumnType=Integer, type_=Integer) def test_column_with_db_column_name_in_kwargs(self): registry = self.init_registry(simple_column, ColumnType=Integer, db_column_name='another_name') test = registry.Test.insert(col=1) assert test.col == 1 res = registry.execute('select id from test where another_name=1') assert res.fetchone()[0] == test.id def test_column_with_foreign_key(self): registry = self.init_registry(column_with_foreign_key) registry.Test.insert(name='test') registry.Test2.insert(test='test') def test_column_with_foreign_key_with_schema(self, db_schema): registry = self.init_registry(column_with_foreign_key_with_schema) registry.Test.insert(name='test') registry.Test2.insert(test='test') def test_column_with_foreign_key_with_diff_schema1(self, db_schema): registry = self.init_registry(column_with_foreign_key_with_diff_schema1) registry.Test.insert(name='test') registry.Test2.insert(test='test') def test_column_with_foreign_key_with_diff_schema2(self, db_schema): registry = self.init_registry(column_with_foreign_key_with_diff_schema2) registry.Test.insert(name='test') registry.Test2.insert(test='test') def test_integer_str_foreign_key(self): registry = self.init_registry( simple_column, ColumnType=Integer, foreign_key='Model.Test=>id') test = registry.Test.insert() test2 = registry.Test.insert(col=test.id) assert test2.col == test.id def test_setter_decimal(self): registry = self.init_registry(simple_column, ColumnType=Decimal) test = registry.Test.insert() test.col = '1.0' assert test.col == D('1.0') def test_boolean_with_default(self): registry = self.init_registry(simple_column, ColumnType=Boolean, default=False) test = registry.Test.insert() assert test.col is False def test_string_with_False(self): registry = self.init_registry(simple_column, ColumnType=String) test = registry.Test.insert(col=False) assert test.col is False self.registry.flush() self.registry.expire(test, ['col']) assert test.col == '' def test_string_set_False(self): registry = self.init_registry(simple_column, ColumnType=String) test = registry.Test.insert() test.col = False assert test.col is False self.registry.flush() self.registry.expire(test, ['col']) assert test.col == '' def test_string_query_False(self): registry = self.init_registry(simple_column, ColumnType=String) test = registry.Test.insert() self.registry.Test.query().filter_by(id=test.id).update({'col': False}) assert test.col is False self.registry.expire(test, ['col']) assert test.col == '' @pytest.mark.skipif(not has_cryptography, reason="cryptography is not installed") def test_string_with_encrypt_key_defined_by_configuration(self): Configuration.set('default_encrypt_key', 'secretkey') registry = self.init_registry(simple_column, ColumnType=String, encrypt_key=True) test = registry.Test.insert(col='col') registry.session.commit() assert test.col == 'col' res = registry.execute('select col from test where id = %s' % test.id) res = res.fetchall()[0][0] assert res != 'col' del Configuration.configuration['default_encrypt_key'] def test_string_with_size(self): registry = self.init_registry( simple_column, ColumnType=String, size=100) test = registry.Test.insert(col='col') assert test.col == 'col' @pytest.mark.skipif(not has_passlib, reason="passlib is not installed") def test_password(self): registry = self.init_registry(simple_column, ColumnType=Password, crypt_context={'schemes': ['md5_crypt']}) test = registry.Test.insert(col='col') assert test.col == 'col' assert registry.execute('Select col from test').fetchone()[0] != 'col' def test_text_with_False(self): registry = self.init_registry(simple_column, ColumnType=Text) test = registry.Test.insert(col=False) assert test.col is False self.registry.flush() self.registry.expire(test, ['col']) assert test.col == '' def test_text_set_False(self): registry = self.init_registry(simple_column, ColumnType=Text) test = registry.Test.insert() test.col = False assert test.col is False self.registry.flush() self.registry.expire(test, ['col']) assert test.col == '' def test_text_query_False(self): registry = self.init_registry(simple_column, ColumnType=Text) test = registry.Test.insert() self.registry.Test.query().filter_by(id=test.id).update({'col': False}) assert test.col is False self.registry.expire(test, ['col']) assert test.col == '' def test_datetime_none_value(self, dt_column_type): registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=None) assert test.col is None def test_datetime_str_conversion_1(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = datetime.datetime.now().replace(tzinfo=timezone) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now.strftime('%Y-%m-%d %H:%M:%S.%f%z')) assert test.col == now def test_datetime_str_conversion_2(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now.strftime('%Y-%m-%d %H:%M:%S.%f%Z')) assert test.col == now def test_datetime_str_conversion_3(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now.strftime('%Y-%m-%d %H:%M:%S.%f')) assert test.col == now def test_datetime_str_conversion_4(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now.strftime('%Y-%m-%d %H:%M:%S')) assert test.col == now.replace(microsecond=0) def test_datetime_by_property(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = datetime.datetime.now().replace(tzinfo=timezone) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() test.col = now assert test.col == now def test_datetime_by_property_none_value(self, dt_column_type): registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() test.col = None assert test.col is None def test_datetime_str_conversion_1_by_property(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = datetime.datetime.now().replace(tzinfo=timezone) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() test.col = now.strftime('%Y-%m-%d %H:%M:%S.%f%z') assert test.col == now def test_datetime_str_conversion_2_by_property(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() test.col = now.strftime('%Y-%m-%d %H:%M:%S.%f%Z') assert test.col == now def test_datetime_str_conversion_3_by_property(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() test.col = now.strftime('%Y-%m-%d %H:%M:%S.%f') assert test.col == now def test_datetime_str_conversion_4_by_property(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() test.col = now.strftime('%Y-%m-%d %H:%M:%S') assert test.col == now.replace(microsecond=0) def test_datetime_by_query(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = datetime.datetime.now().replace(tzinfo=timezone) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() registry.Test.query().update(dict(col=now)) assert test.col == now def test_datetime_by_query_none_value(self, dt_column_type): registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() registry.Test.query().update(dict(col=None)) assert test.col is None @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_str_conversion_1_by_query(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = datetime.datetime.now().replace(tzinfo=timezone) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() registry.Test.query().update( dict(col=now.strftime('%Y-%m-%d %H:%M:%S.%f%z'))) registry.expire(test, ['col']) assert test.col == now @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_str_conversion_2_by_query(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() registry.Test.query().update( dict(col=now.strftime('%Y-%m-%d %H:%M:%S.%f%Z'))) registry.expire(test, ['col']) assert test.col == now @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_str_conversion_3_by_query(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() registry.Test.query().update( dict(col=now.strftime('%Y-%m-%d %H:%M:%S.%f'))) registry.expire(test, ['col']) assert test.col == now @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_str_conversion_4_by_query(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert() registry.Test.query().update( dict(col=now.strftime('%Y-%m-%d %H:%M:%S'))) registry.expire(test, ['col']) assert test.col == now.replace(microsecond=0) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_by_query_filter(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = datetime.datetime.now().replace(tzinfo=timezone) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now) Test = registry.Test assert Test.query().filter(Test.col == now).one() is test @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_str_conversion_1_by_query_filter(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = datetime.datetime.now().replace(tzinfo=timezone) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now) Test = registry.Test assert Test.query().filter( Test.col == now.strftime('%Y-%m-%d %H:%M:%S.%f%z')).one() is test @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_str_conversion_2_by_query_filter(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now) Test = registry.Test assert Test.query().filter( Test.col == now.strftime('%Y-%m-%d %H:%M:%S.%f%Z')).one() is test @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #87') def test_datetime_str_conversion_3_by_query_filter(self, dt_column_type): timezone = pytz.timezone(time.tzname[0]) now = timezone.localize(datetime.datetime.now()) registry = self.init_registry(simple_column, ColumnType=dt_column_type) test = registry.Test.insert(col=now) Test = registry.Test assert Test.query().filter( Test.col == now.strftime('%Y-%m-%d %H:%M:%S.%f')).one() is test def test_datetime_without_auto_update_1(self, dt_column_type): def add_in_registry(): from anyblok import Declarations @Declarations.register(Declarations.Model) class Test: id = Integer(primary_key=True) update_at = DateTime() val = String() registry = self.init_registry(add_in_registry) test = registry.Test.insert(val='first add') assert test.update_at is None test.val = 'other' registry.flush() assert test.update_at is None def test_datetime_without_auto_update_2(self, dt_column_type): def add_in_registry(): from anyblok import Declarations @Declarations.register(Declarations.Model) class Test: id = Integer(primary_key=True) update_at = DateTime(auto_update=False) val = String() registry = self.init_registry(add_in_registry) test = registry.Test.insert(val='first add') assert test.update_at is None test.val = 'other' registry.flush() assert test.update_at is None def test_datetime_with_auto_update(self, dt_column_type): def add_in_registry(): from anyblok import Declarations @Declarations.register(Declarations.Model) class Test: id = Integer(primary_key=True) update_at = DateTime(auto_update=True) val = String() registry = self.init_registry(add_in_registry) test = registry.Test.insert(val='first add') assert test.update_at is None test.val = 'other' registry.flush() assert test.update_at is not None def test_datetime_with_default_timezone_tz(self, dt_column_type): import datetime import pytz timezone = pytz.timezone('Asia/Tokyo') now = datetime.datetime.now() registry = self.init_registry( simple_column, ColumnType=dt_column_type, default_timezone=timezone) field = registry.loaded_namespaces_first_step['Model.Test']['col'] assert field.default_timezone is timezone test = registry.Test.insert(col=now) assert test.col.tzinfo.zone is timezone.zone def test_datetime_with_default_timezone_str(self, dt_column_type): import datetime import pytz timezone = pytz.timezone('Asia/Tokyo') now = datetime.datetime.now() registry = self.init_registry( simple_column, ColumnType=dt_column_type, default_timezone='Asia/Tokyo') field = registry.loaded_namespaces_first_step['Model.Test']['col'] assert field.default_timezone == timezone test = registry.Test.insert(col=now) assert test.col.tzinfo.zone == timezone.zone def test_datetime_with_default_global_timezone_str(self, dt_column_type): import datetime import pytz timezone = pytz.timezone('Asia/Tokyo') now = datetime.datetime.now() with tmp_configuration(default_timezone='Asia/Tokyo'): registry = self.init_registry(simple_column, ColumnType=dt_column_type) field = registry.loaded_namespaces_first_step['Model.Test']['col'] assert field.default_timezone is timezone test = registry.Test.insert(col=now) assert test.col.tzinfo.zone is timezone.zone def test_selection(self): SELECTIONS = [ ('admin', 'Admin'), ('regular-user', 'Regular user') ] registry = self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) test = registry.Test.insert(col=SELECTIONS[0][0]) assert test.col == SELECTIONS[0][0] assert test.col.label == SELECTIONS[0][1] test = registry.Test.query().first() assert test.col == SELECTIONS[0][0] assert test.col.label == SELECTIONS[0][1] with pytest.raises(FieldException): test.col = 'bad value' def test_selection_with_only_one_value(self): SELECTIONS = [ ('admin', 'Admin'), ] registry = self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) test = registry.Test.insert(col=SELECTIONS[0][0]) assert test.col == SELECTIONS[0][0] assert test.col.label == SELECTIONS[0][1] test = registry.Test.query().first() assert test.col == SELECTIONS[0][0] assert test.col.label == SELECTIONS[0][1] with pytest.raises(FieldException): test.col = 'bad value' def test_selection_without_value(self): self.init_registry(simple_column, ColumnType=Selection, selections=[]) def test_selection_autodoc(self): SELECTIONS = [ ('admin', 'Admin'), ] registry = self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) column = registry.System.Column.query().filter_by( model='Model.Test', name='col').one() assert column._description() == { 'id': 'col', 'label': 'Col', 'model': None, 'nullable': True, 'primary_key': False, 'selections': [ ('admin', 'Admin'), ], 'type': 'Selection', } def test_selection_with_none_value(self): SELECTIONS = [ ('admin', 'Admin'), ('regular-user', 'Regular user') ] registry = self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) t = registry.Test.insert() assert t.col is None @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #90') def test_selection_change_by_query(self): SELECTIONS = [ ('admin', 'Admin'), ('regular-user', 'Regular user') ] registry = self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) registry.Test.insert(col=SELECTIONS[0][0]) with pytest.raises(StatementError): registry.Test.query().update({'col': 'bad value'}) def test_selection_like_comparator(self): SELECTIONS = [ ('admin', 'Admin'), ('regular-user', 'Regular user') ] registry = self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) Test = registry.Test t = Test.insert(col=SELECTIONS[0][0]) t1 = Test.query().filter(Test.col.like('%admin%')).one() assert t is t1 def test_selection_key_other_than_str(self): SELECTIONS = [ (0, 'Admin'), (1, 'Regular user') ] with pytest.raises(FieldException): self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) def test_selection_comparator(self): SELECTIONS = [ ('admin', 'Admin'), ('regular-user', 'Regular user') ] registry = self.init_registry( simple_column, ColumnType=Selection, selections=SELECTIONS) registry.Test.insert(col=SELECTIONS[0][0]) registry.Test.query().filter( registry.Test.col.in_(['admin', 'regular-user'])).first() def test_selection_use_method(self): SELECTIONS = [ ('admin', 'Admin'), ('regular-user', 'Regular user') ] def add_selection(): @register(Model) class Test: id = Integer(primary_key=True) col = Selection(selections='get_selection') @classmethod def get_selection(cls): return SELECTIONS registry = self.init_registry(add_selection) registry.Test.insert(col=SELECTIONS[0][0]) registry.Test.query().filter( registry.Test.col.in_(['admin', 'regular-user'])).first() def test_json_update(self): registry = self.init_registry(simple_column, ColumnType=Json) test = registry.Test.insert(col={'a': 'test'}) test.col['b'] = 'test' assert test.col == {'a': 'test', 'b': 'test'} @pytest.mark.skipif(sgdb_in(['MariaDB', 'MsSQL']), reason='JSON is not existing in this SGDB') def test_json_simple_filter(self): registry = self.init_registry(simple_column, ColumnType=Json) Test = registry.Test Test.insert(col={'a': 'test'}) Test.insert(col={'a': 'test'}) Test.insert(col={'b': 'test'}) assert Test.query().filter( Test.col['a'].cast(SA_String) == '"test"').count() == 2 def test_json_null(self): registry = self.init_registry(simple_column, ColumnType=Json) Test = registry.Test Test.insert(col=None) Test.insert(col=None) Test.insert(col={'a': 'test'}) assert Test.query().filter(Test.col.is_(None)).count() == 2 assert Test.query().filter(Test.col.isnot(None)).count() == 1 def test_add_default_classmethod(self): val = 'test' def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) val = String(default="get_val") @classmethod def get_val(cls): return val registry = self.init_registry(add_in_registry) t = registry.Test.insert() assert t.val == val def test_add_default_without_classmethod(self): value = 'test' def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) val = String(default="get_val") def get_val(cls): return value registry = self.init_registry(add_in_registry) t = registry.Test.insert() assert t.val == "get_val" def test_add_default_by_var(self): value = 'test' def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) val = String(default=value) registry = self.init_registry(add_in_registry) t = registry.Test.insert() assert t.val == value def test_add_default(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) val = String(default='value') registry = self.init_registry(add_in_registry) t = registry.Test.insert() assert t.val == 'value' def test_add_field_as_default(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) val = String(default='val') registry = self.init_registry(add_in_registry) t = registry.Test.insert() assert t.val == 'val' @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #89') def test_sequence(self): registry = self.init_registry(simple_column, ColumnType=Sequence) assert registry.Test.insert().col == "1" assert registry.Test.insert().col == "2" assert registry.Test.insert().col == "3" assert registry.Test.insert().col == "4" Seq = registry.System.Sequence assert Seq.query().filter(Seq.code == 'Model.Test=>col').count() == 1 @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #89') def test_sequence_with_primary_key(self): registry = self.init_registry(simple_column, ColumnType=Sequence, primary_key=True) assert registry.Test.insert().col == "1" assert registry.Test.insert().col == "2" @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #89') def test_sequence_with_code_and_formater(self): registry = self.init_registry(simple_column, ColumnType=Sequence, code="SO", formater="{code}-{seq:06d}") assert registry.Test.insert().col == "SO-000001" assert registry.Test.insert().col == "SO-000002" assert registry.Test.insert().col == "SO-000003" assert registry.Test.insert().col == "SO-000004" Seq = registry.System.Sequence assert Seq.query().filter(Seq.code == 'SO').count() == 1 def test_sequence_with_foreign_key(self): with pytest.raises(FieldException): self.init_registry(simple_column, ColumnType=Sequence, foreign_key=Model.System.Model.use('name')) def test_sequence_with_default(self): with pytest.raises(FieldException): self.init_registry(simple_column, ColumnType=Sequence, default='default value') @pytest.mark.skipif(not has_colour, reason="colour is not installed") def test_color(self): color = '#F5F5F5' registry = self.init_registry(simple_column, ColumnType=Color) test = registry.Test.insert(col=color) assert test.col.hex == colour.Color(color).hex @pytest.mark.skipif(not has_colour, reason="colour is not installed") def test_setter_color(self): color = '#F5F5F5' registry = self.init_registry(simple_column, ColumnType=Color) test = registry.Test.insert() test.col = color assert test.col.hex == colour.Color(color).hex def test_uuid_binary_3(self): from uuid import uuid3, NAMESPACE_DNS uuid = uuid3(NAMESPACE_DNS, 'python.org') registry = self.init_registry(simple_column, ColumnType=UUID) test = registry.Test.insert(col=uuid) assert test.col is uuid def test_uuid_binary_4(self): from uuid import uuid4 uuid = uuid4() registry = self.init_registry(simple_column, ColumnType=UUID) test = registry.Test.insert(col=uuid) assert test.col is uuid def test_uuid_binary_5(self): from uuid import uuid5, NAMESPACE_DNS uuid = uuid5(NAMESPACE_DNS, 'python.org') registry = self.init_registry(simple_column, ColumnType=UUID) test = registry.Test.insert(col=uuid) assert test.col is uuid def test_uuid_char32(self): uuid = uuid1() registry = self.init_registry(simple_column, ColumnType=UUID, binary=False) test = registry.Test.insert(col=uuid) assert test.col is uuid @pytest.mark.skipif(not has_furl, reason="furl is not installed") def test_setter_URL(self): f = 'http://doc.anyblok.org' registry = self.init_registry(simple_column, ColumnType=URL) test = registry.Test.insert() test.col = f assert test.col.url == f @pytest.mark.skipif(not has_furl, reason="furl is not installed") def test_URL_2(self): f = 'http://doc.anyblok.org' registry = self.init_registry(simple_column, ColumnType=URL) test = registry.Test.insert(col=f) assert test.col.url == f @pytest.mark.skipif(not has_furl, reason="furl is not installed") def test_URL_3(self): f = 'http://doc.anyblok.org' registry = self.init_registry(simple_column, ColumnType=URL) registry.Test.insert(col=f) Test = registry.Test test = Test.query().filter(Test.col == f).one() assert test.col.url == f @pytest.mark.skipif(not has_furl, reason="furl is not installed") def test_URL_4(self): f = furl.furl('http://doc.anyblok.org') registry = self.init_registry(simple_column, ColumnType=URL) registry.Test.insert(col=f) Test = registry.Test test = Test.query().filter(Test.col == f).one() assert test.col.url == f.url @pytest.mark.skipif(not has_phonenumbers, reason="phonenumbers is not installed") def test_phonenumbers_at_insert(self): registry = self.init_registry(simple_column, ColumnType=PhoneNumber) test = registry.Test.insert(col='+120012301') assert test.col.national == '20012301' getted = registry.execute('Select col from test').fetchone()[0] assert getted == '+120012301' @pytest.mark.skipif(not has_phonenumbers, reason="phonenumbers is not installed") def test_phonenumbers_at_setter(self): registry = self.init_registry(simple_column, ColumnType=PhoneNumber) test = registry.Test.insert() test.col = '+120012301' assert test.col.national == '20012301' registry.flush() getted = registry.execute('Select col from test').fetchone()[0] assert getted == '+120012301' @pytest.mark.skipif(not has_phonenumbers, reason="phonenumbers is not installed") def test_phonenumbers_obj_at_insert(self): registry = self.init_registry(simple_column, ColumnType=PhoneNumber) col = PN("+120012301", None) test = registry.Test.insert(col=col) assert test.col == col getted = registry.execute('Select col from test').fetchone()[0] assert getted == '+120012301' @pytest.mark.skipif(not has_phonenumbers, reason="phonenumbers is not installed") def test_phonenumbers_obj_at_setter(self): registry = self.init_registry(simple_column, ColumnType=PhoneNumber) test = registry.Test.insert() test.col = PN("+120012301", None) assert test.col.national == '20012301' registry.flush() getted = registry.execute('Select col from test').fetchone()[0] assert getted == '+120012301' @pytest.mark.skipif(not has_phonenumbers, reason="phonenumbers is not installed") def test_phonenumbers_obj_at_setter_with_empty_value(self): registry = self.init_registry(simple_column, ColumnType=PhoneNumber) test = registry.Test.insert() test.col = "" assert test.col == '' registry.flush() assert registry.execute('Select col from test').fetchone()[0] == '' def test_email_at_setter(self): registry = self.init_registry(simple_column, ColumnType=Email) test = registry.Test.insert() test.col = '*****@*****.**' assert test.col == '*****@*****.**' assert registry.Test.query().filter_by( col='*****@*****.**').count() == 1 @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_at_insert(self): registry = self.init_registry(simple_column, ColumnType=Country) test = registry.Test.insert(col='FR') assert test.col is pycountry.countries.get(alpha_2='FR') assert test.col.name == 'France' assert registry.execute('Select col from test').fetchone()[0] == 'FRA' @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_at_insert_with_alpha_3(self): registry = self.init_registry( simple_column, ColumnType=Country, mode='alpha_3') test = registry.Test.insert(col='FRA') assert test.col is pycountry.countries.get(alpha_2='FR') assert test.col.name == 'France' assert registry.execute('Select col from test').fetchone()[0] == 'FRA' @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_at_insert_with_object(self): registry = self.init_registry(simple_column, ColumnType=Country) fr = pycountry.countries.get(alpha_2='FR') test = registry.Test.insert(col=fr) assert test.col is fr assert test.col.name == 'France' assert registry.execute('Select col from test').fetchone()[0] == 'FRA' @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_at_update(self): registry = self.init_registry(simple_column, ColumnType=Country) test = registry.Test.insert() test.col = 'FR' registry.flush() assert test.col is pycountry.countries.get(alpha_2='FR') assert test.col.name == 'France' assert registry.execute('Select col from test').fetchone()[0] == 'FRA' @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_at_update_with_alpha_3(self): registry = self.init_registry( simple_column, ColumnType=Country, mode='alpha_3') test = registry.Test.insert() test.col = 'FRA' registry.flush() assert test.col is pycountry.countries.get(alpha_2='FR') assert test.col.name == 'France' assert registry.execute('Select col from test').fetchone()[0] == 'FRA' @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_at_update_with_object(self): registry = self.init_registry(simple_column, ColumnType=Country) fr = pycountry.countries.get(alpha_2='FR') test = registry.Test.insert() test.col = fr registry.flush() assert test.col is fr assert test.col.name == 'France' assert registry.execute('Select col from test').fetchone()[0] == 'FRA' @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_query_is_with_object(self): registry = self.init_registry(simple_column, ColumnType=Country) Test = registry.Test fr = pycountry.countries.get(alpha_2='FR') Test.insert(col='FR') assert Test.query().filter(Test.col == fr).count() == 1 @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_query_is_with_alpha_3(self): registry = self.init_registry(simple_column, ColumnType=Country) Test = registry.Test Test.insert(col='FR') assert Test.query().filter(Test.col == 'FRA').count() == 1 @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") def test_pycoundtry_query_insert_wrong(self): registry = self.init_registry(simple_column, ColumnType=Country) with pytest.raises(LookupError): registry.Test.insert(col='WG') @pytest.mark.skipif(not has_pycountry, reason="pycountry is not installed") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #90') def test_pycoundtry_query_insert_by_wrong_query(self): registry = self.init_registry(simple_column, ColumnType=Country) with pytest.raises(Exception): registry.execute("insert into test (col) values ('WG2')") @pytest.mark.skipif(not has_cryptography, reason="cryptography is not installed") def test_insert_encrypt_key_columns(self, column_definition): column, value, kwargs = column_definition registry = self.init_registry(simple_column, ColumnType=column, encrypt_key='secretkey', **kwargs) test = registry.Test.insert(col=value) registry.session.commit() assert test.col == value res = registry.execute('select col from test where id = %s' % test.id) res = res.fetchall()[0][0] assert res != test.col def test_foreign_key_on_mapper_issue_112(self): def add_in_registry(): @Declarations.register(Declarations.Model) class Template: code = String(primary_key=True, db_column_name='ProductId') @Declarations.register(Declarations.Model) class Item: id = Integer(primary_key=True, db_column_name='ProductDetailId') template_code = String( db_column_name='ProductId', foreign_key=Model.Template.use('code')) registry = self.init_registry(add_in_registry) registry.Template.insert(code='test') registry.Item.insert(template_code='test') with pytest.raises(Exception): registry.Item.insert(template_code='other') def test_foreign_key_on_mapper_issue_112_with_schema(self, db_schema): def add_in_registry(): @Declarations.register(Declarations.Model) class Template: __db_schema__ = 'test_db_column_schema' code = String(primary_key=True, db_column_name='ProductId') @Declarations.register(Declarations.Model) class Item: __db_schema__ = 'test_db_column_schema' id = Integer(primary_key=True, db_column_name='ProductDetailId') template_code = String( db_column_name='ProductId', foreign_key=Model.Template.use('code')) registry = self.init_registry(add_in_registry) registry.Template.insert(code='test') registry.Item.insert(template_code='test') with pytest.raises(Exception): registry.Item.insert(template_code='other')
from anyblok.config import Configuration from anyblok.testing import tmp_configuration from sqlalchemy import Integer as SA_Integer, String as SA_String from sqlalchemy.exc import StatementError from anyblok import Declarations from anyblok.field import FieldException from .conftest import init_registry, reset_db from anyblok.column import ( Column, Boolean, Json, String, BigInteger, Text, Selection, Date, DateTime, Time, Interval, Decimal, Float, LargeBinary, Integer, Sequence, Color, Password, UUID, URL, PhoneNumber, Email, Country, TimeStamp) time_params = [DateTime] if not sgdb_in(['MsSQL']): time_params.append(TimeStamp) @pytest.fixture(params=time_params) def dt_column_type(request): return request.param COLUMNS = [ (Selection, 'test', {'selections': {'test': 'test'}}), (Boolean, True, {}), (Boolean, False, {}), (String, 'test', {}), (BigInteger, 1, {}), (Text, 'Test', {}),
# This file is a part of the AnyBlok project # # Copyright (C) 2015 Jean-Sebastien SUZANNE <*****@*****.**> # Copyright (C) 2020 Jean-Sebastien SUZANNE <*****@*****.**> # # This Source Code Form is subject to the terms of the Mozilla Public License, # v. 2.0. If a copy of the MPL was not distributed with this file,You can # obtain one at http://mozilla.org/MPL/2.0/. import pytest from anyblok.testing import sgdb_in @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason='ISSUE #89') @pytest.mark.usefixtures('rollback_registry') class TestSystemSequence: def test_nextval_without_prefix_without_suffix(self, rollback_registry): registry = rollback_registry Sequence = registry.System.Sequence seq = Sequence.insert(code='test.sequence') assert seq.current is None assert seq.nextval() == '1' assert seq.nextval() == '2' assert seq.nextval() == '3' assert seq.current == 3 def test_nextval_with_start_value(self, rollback_registry): registry = rollback_registry Sequence = registry.System.Sequence seq = Sequence.insert(code='test.sequence', start=10) assert seq.current is None assert seq.nextval() == '10'
class TestMigrationDbSchema: def test_add_schema(self, registry): registry.migration.schema().add('other_schema') registry.migration.schema('other_schema') registry.migration.schema('other_schema').drop() @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="Can't create empty table") def test_add_table_from_schema(self, registry): schema = registry.migration.schema('test_db_schema') schema.table().add('test2') table = schema.table('test2') assert table.schema == 'test_db_schema' @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="Can't create empty table") def test_add_table(self, registry): registry.migration.table(schema='test_db_schema').add('test2') table = registry.migration.table('test2', schema='test_db_schema') assert table.schema == 'test_db_schema' def test_add_column(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.column().add(Column('new_column', Integer)) t.column('new_column') def test_add_unique_constraint(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.unique('unique_constraint').add(t.column('other')) registry.Test.insert(other='One entry') with pytest.raises(IntegrityError): registry.Test.insert(other='One entry') def test_drop_schema(self, registry): schema = registry.migration.schema('test_db_schema') schema.table('test').drop() schema.table('testfk').drop() schema.table('testunique').drop() schema.table('testfk2').drop() schema.table('testfktarget').drop() schema.table('testindex').drop() if not sgdb_in(['MySQL', 'MariaDB']): schema.table('testcheck').drop() schema.drop() with pytest.raises(MigrationException): registry.migration.schema('test_db_schema') # MySQL waiting that this schema exist for the next test registry.migration.schema().add('test_db_schema') def test_drop_table(self, registry): registry.migration.table('test', schema='test_db_schema').drop() with pytest.raises(MigrationException): registry.migration.table('Test', schema='test_db_schema') def test_drop_column(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.column('other').drop() with pytest.raises(MigrationException): t.column('other') @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="Can't rename schema #122") def test_alter_schema_name(self, registry): registry.migration.schema('test_db_schema').alter(name='test_db_other') with pytest.raises(MigrationException): registry.migration.schema('test_db_schema') registry.migration.schema('test_db_other') registry.migration.schema('test_db_other').table('test') def test_alter_table_name(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.alter(name='othername') registry.migration.table('othername', schema='test_db_schema') with pytest.raises(MigrationException): registry.migration.table('test') def test_alter_column_name(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.column('other').alter(name='othername') t.column('othername') with pytest.raises(MigrationException): t.column('other') def test_index(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.index().add(t.column('integer')) t.index(t.column('integer')).drop() @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="FIXME: can't create foreign key") def test_alter_column_foreign_key(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.foreign_key('my_fk').add(['other'], [registry.System.Blok.name]) t.foreign_key('my_fk').drop() def test_constraint_unique(self, registry): t = registry.migration.table('test', schema='test_db_schema') t.unique(name='test_unique_constraint').add(t.column('other')) t.unique(name='test_unique_constraint').drop() @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="Can't drop check constraint issue #93") def test_constraint_check(self, registry): t = registry.migration.table('test', schema='test_db_schema') Test = registry.Test t.check('test').add(Test.other != 'test') # particuliar case of check constraint t.check('anyblok_ck_test__test').drop() def test_detect_schema_added(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.TestFK.__table__.drop(bind=conn) registry.TestUnique.__table__.drop(bind=conn) registry.TestFK2.__table__.drop(bind=conn) registry.TestFKTarget.__table__.drop(bind=conn) registry.TestIndex.__table__.drop(bind=conn) if not sgdb_in(['MySQL', 'MariaDB']): registry.TestCheck.__table__.drop(bind=conn) conn.execute(DropSchema('test_db_schema')) report = registry.migration.detect_changed(schema_only=True) assert report.log_has("Add schema test_db_schema") report.apply_change() report = registry.migration.detect_changed(schema_only=True) assert not report.log_has("Add schema test_db_schema") def test_detect_table_added(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add table test_db_schema.test") report.apply_change() report = registry.migration.detect_changed() assert not report.log_has("Add table test_db_schema.test") def test_detect_column_added(self, registry): # Remove a column on the table force the detection to found new column # which is existing in metadata but not in table with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table('test', MetaData(), Column('integer', Integer, primary_key=True), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add test.other") report.apply_change() report = registry.migration.detect_changed() assert not report.log_has("Add test.other") def test_detect_table_removed(self, registry): with cnx(registry) as conn: Table('test2', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), schema='test_db_schema').create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop Table test_db_schema.test2") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop Table test_db_schema.test2") def test_detect_column_removed(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table('test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop Column test.other2") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop Column test.other2") def test_detect_nullable(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table('test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), nullable=False), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Alter test.other") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Alter test.other")) def test_detect_add_index_constraint(self, registry): with cnx(registry) as conn: registry.TestIndex.__table__.drop(bind=conn) registry.TestIndex.__table__ = Table('testindex', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), schema='test_db_schema') registry.TestIndex.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add index constraint on testindex (other)") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Add index constraint on testindex (other)")) def test_detect_add_column_with_index_constraint(self, registry): with cnx(registry) as conn: registry.TestIndex.__table__.drop(bind=conn) registry.TestIndex.__table__ = Table('testindex', MetaData(), Column('integer', Integer, primary_key=True), schema='test_db_schema') registry.TestIndex.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add testindex.other") assert report.log_has("Add index constraint on testindex (other)") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Add testindex.other")) assert not ( report.log_has("Add index constraint on testindex (other)")) def test_detect_drop_anyblok_index(self, registry): with cnx(registry) as conn: conn.execute( text("""CREATE INDEX anyblok_ix_test__other ON test_db_schema.test (other);""")) report = registry.migration.detect_changed() assert report.log_has( "Drop index anyblok_ix_test__other on test_db_schema.test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Drop index anyblok_ix_test__other on test_db_schema.test")) def test_detect_type(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table('test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Alter test.other") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Alter test.other")) def test_detect_primary_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table('test', MetaData(), Column('integer', Integer, nullable=False), Column('other', String(64), primary_key=True), schema='test_db_schema') registry.Test.__table__.create(bind=conn) with pytest.raises(MigrationException): registry.migration.detect_changed() def test_detect_add_foreign_key(self, registry): with cnx(registry) as conn: registry.TestFK.__table__.drop(bind=conn) registry.TestFK.__table__ = Table('testfk', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), schema='test_db_schema') registry.TestFK.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add Foreign keys on (testfk.other) => " "(test_db_schema.testfktarget.integer)") report.apply_change() report = registry.migration.detect_changed() assert not report.log_has("Add Foreign keys on (testfk.other) => " "(test_db_schema.testfktarget.integer)") @pytest.mark.skipif(sgdb_in(['MsSQL']), reason="MsSQL does not change fk") def test_detect_foreign_key_options_changed(self, registry): with cnx(registry) as conn: registry.TestFK2.__table__.drop(bind=conn) meta = MetaData() meta._add_table('testfktarget', None, registry.TestFKTarget.__table__) registry.TestFK2.__table__ = Table( 'testfk2', meta, Column('integer', Integer, primary_key=True), Column('other', Integer, ForeignKey('testfktarget.integer')), schema='test_db_schema') registry.TestFK2.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop Foreign keys on testfk2.other => " "test_db_schema.testfktarget.integer") assert report.log_has("Add Foreign keys on (testfk2.other) => " "(test_db_schema.testfktarget.integer)") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="FIXME: can't create foreign key") def test_detect_drop_anyblok_foreign_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData(naming_convention=naming_convention) meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64), ForeignKey('system_blok.name')), schema='test_db_schema') registry.Test.__table__.create(bind=conn) # anyblok_fk_test__other_on_system_blok__name report = registry.migration.detect_changed() message = ("Drop Foreign keys on test.other => %ssystem_blok.name") % ( 'dbo.' if sgdb_in(['MsSQL']) else '') assert report.log_has(message) report.apply_change() report = registry.migration.detect_changed() assert not report.log_has(message) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="FIXME: can't create foreign key") def test_detect_drop_column_with_foreign_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData(naming_convention=naming_convention) meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64), ForeignKey('system_blok.name')), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() message = ("Drop Foreign keys on test.other2 => %ssystem_blok.name" ) % ('dbo.' if sgdb_in(['MsSQL']) else '') assert report.log_has(message) report.apply_change() report = registry.migration.detect_changed() assert not report.log_has(message) @pytest.mark.skipif(sgdb_in(['MsSQL']), reason="MsSQL does not add unique #121") def test_detect_add_unique_constraint(self, registry): with cnx(registry) as conn: registry.TestUnique.__table__.drop(bind=conn) registry.TestUnique.__table__ = Table('testunique', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), schema='test_db_schema') registry.TestUnique.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add unique constraint on testunique (other)") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Add unique constraint on testunique (other)")) @pytest.mark.skipif(sgdb_in(['MsSQL']), reason="MsSQL does not add unique #121") def test_detect_add_column_with_unique_constraint(self, registry): with cnx(registry) as conn: registry.TestUnique.__table__.drop(bind=conn) registry.TestUnique.__table__ = Table('testunique', MetaData(), Column('integer', Integer, primary_key=True), schema='test_db_schema') registry.TestUnique.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add unique constraint on testunique (other)") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Add unique constraint on testunique (other)")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="MySQL transform unique constraint on index") @pytest.mark.skipif(sgdb_in(['MsSQL']), reason="MsSQL does not drop unique #121") def test_detect_drop_unique_anyblok_constraint(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), Column('other', String(64), unique=True), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has( "Drop constraint anyblok_uq_test__other on test_db_schema.test") report.apply_change() report = registry.migration.detect_changed() assert not report.log_has( "Drop constraint anyblok_uq_test__other on test_db_schema.test") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="No CheckConstraint works #90") def test_detect_add_check_constraint(self, registry): with cnx(registry) as conn: registry.TestCheck.__table__.drop(bind=conn) registry.TestCheck.__table__ = Table( 'testcheck', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), schema='test_db_schema') registry.TestCheck.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has( "Add check constraint anyblok_ck_testcheck__test " "on test_db_schema.testcheck") report.apply_change() report = registry.migration.detect_changed() assert not report.log_has( "Add check constraint anyblok_ck_testcheck__test " "on test_db_schema.testcheck") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB', 'MsSQL']), reason="No CheckConstraint works #90") def test_detect_drop_check_anyblok_constraint(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), Column('other', String(64), CheckConstraint("other != 'test'", name='check')), schema='test_db_schema') registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop check constraint anyblok_ck_test__check " "on test_db_schema.test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Drop check constraint anyblok_ck_test__check " "on test_db_schema.test"))
# -*- coding: utf-8 -*- # This file is a part of the AnyBlok project # # Copyright (C) 2014 Jean-Sebastien SUZANNE <*****@*****.**> # Copyright (C) 2019 Jean-Sebastien SUZANNE <*****@*****.**> # # This Source Code Form is subject to the terms of the Mozilla Public License, # v. 2.0. If a copy of the MPL was not distributed with this file,You can # obtain one at http://mozilla.org/MPL/2.0/. import pytest from anyblok.testing import sgdb_in from anyblok.blok import BlokManager from anyblok.registry import RegistryException, RegistryConflictingException @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason='Not for MySQL and MariaDB') class TestBlok: @pytest.fixture(autouse=True) def transact(self, request, registry_testblok): transaction = registry_testblok.begin_nested() request.addfinalizer(transaction.rollback) return def test_blok_exist(self, registry_testblok): registry = registry_testblok Blok = registry.System.Blok query = Blok.query().filter(Blok.name == 'test-blok1') if not query.count(): pytest.fail('No blok found')
class TestField2: @pytest.fixture(autouse=True) def close_registry(self, request, bloks_loaded): def close(): if hasattr(self, 'registry'): self.registry.close() request.addfinalizer(close) def init_registry(self, *args, **kwargs): self.registry = init_registry(*args, **kwargs) return self.registry def test_field_without_name(self): self.init_registry(field_without_name) def test_field_function_fset(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) _name = String() name = Function(fget='fget', fset='fset', fdel='fdel', fexpr='fexpr') def fget(self): return self._name def fset(self, value): self._name = value def fdel(self): self._name = None @classmethod def fexpr(cls): return cls._name registry = self.init_registry(add_in_registry) t = registry.Test.insert(name='Jean-Sebastien SUZANNE') assert t._name == 'Jean-Sebastien SUZANNE' t = registry.Test.query().first() t.name = 'Mister ANYBLOK' assert t._name == 'Mister ANYBLOK' t.update(name='Jean-Sebastien SUZANNE') assert t._name == 'Jean-Sebastien SUZANNE' def test_class_hasattr(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) val1 = Integer() val2 = Function(fget='fget', fset='fset') def fget(self): return 2 * self.val1 registry = self.init_registry(add_in_registry) registry.Test.val2 @pytest.mark.skipif(sgdb_in(['MariaDB']), reason='JSON is not existing in this SGDB') def test_field_json_related_with_missing_json_column(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) properties = Json() name = JsonRelated(keys=['name']) with pytest.raises(FieldException): self.init_registry(add_in_registry) @pytest.mark.skipif(sgdb_in(['MariaDB']), reason='JSON is not existing in this SGDB') def test_field_json_related_with_missing_keys(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) properties = Json() name = JsonRelated(json_column='properties') with pytest.raises(FieldException): self.init_registry(add_in_registry) @pytest.mark.skipif(sgdb_in(['MariaDB']), reason='JSON is not existing in this SGDB') def test_field_json_related_with_adapter(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) properties = Json() name = JsonRelated(json_column='properties', keys=['name'], set_adapter=str, get_adapter=int) registry = self.init_registry(add_in_registry) t = registry.Test.insert() assert t.name is None t.name = 1 assert t.properties == {'name': '1'} t.properties['name'] = '2' assert t.name == 2 @pytest.mark.skipif(sgdb_in(['MariaDB']), reason='JSON is not existing in this SGDB') def test_field_json_related_with_adapter_with_method(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) properties = Json() name = JsonRelated(json_column='properties', keys=['name'], set_adapter='fromint', get_adapter='toint') def fromint(self, value): if value: return str(value) return value def toint(self, value): if value: return int(value) return value registry = self.init_registry(add_in_registry) t = registry.Test.insert() assert t.name is None t.name = 1 assert t.properties == {'name': '1'} t.properties['name'] = '2' assert t.name == 2
class TestJsonRelated: @pytest.fixture(autouse=True) def transact(self, request, registry_json_related): transaction = registry_json_related.begin_nested() request.addfinalizer(transaction.rollback) return @pytest.mark.skipif(sgdb_in(['MariaDB', 'MsSQL']), reason='JSON is not existing in this SGDB') def test_field_json_related_hasattr(self, registry_json_related): registry = registry_json_related registry.Test.name def test_field_json_related_autodoc(self, registry_json_related): registry = registry_json_related registry.loaded_namespaces_first_step['Model.Test'][ 'name'].autodoc_get_properties() def test_field_json_related_get_1(self, registry_json_related): registry = registry_json_related t = registry.Test.insert() assert t.name is None def test_field_json_related_get_2(self, registry_json_related): registry = registry_json_related t = registry.Test.insert(properties={}) assert t.name is None def test_field_json_related_get_3(self, registry_json_related): registry = registry_json_related t = registry.Test.insert(properties={'name': 'jssuzanne'}) assert t.name == 'jssuzanne' def test_field_json_related_del_1(self, registry_json_related): registry = registry_json_related t = registry.Test.insert(properties={'name': 'jssuzanne'}) del t.name assert t.name is None assert t.properties == {'name': None} def test_field_json_related_set_1(self, registry_json_related): registry = registry_json_related t = registry.Test.insert() t.name = 'jssuzanne' assert t.properties == {'name': 'jssuzanne'} def test_field_json_related_set_2(self, registry_json_related): registry = registry_json_related t = registry.Test.insert(properties={}) t.name = 'jssuzanne' assert t.properties == {'name': 'jssuzanne'} def test_field_json_related_set_3(self, registry_json_related): registry = registry_json_related t = registry.Test.insert(properties={'name': 'other'}) t.name = 'jssuzanne' assert t.properties == {'name': 'jssuzanne'} @pytest.mark.skipif(sgdb_in(['MariaDB', 'MsSQL']), reason='JSON is not existing in this SGDB') def test_field_json_related_exp_1(self, registry_json_related): registry = registry_json_related Test = registry.Test Test.insert() query = registry.Test.query().filter( Test.name.cast(types.String) == '"jssuzanne"') assert not (query.count()) @pytest.mark.skipif(sgdb_in(['MariaDB', 'MsSQL']), reason='JSON is not existing in this SGDB') def test_field_json_related_exp_2(self, registry_json_related): registry = registry_json_related Test = registry.Test Test.insert(properties={}) query = registry.Test.query().filter( Test.name.cast(types.String) == '"jssuzanne"') assert not (query.count()) @pytest.mark.skipif(sgdb_in(['MariaDB', 'MsSQL']), reason='JSON is not existing in this SGDB') def test_field_json_related_exp_3(self, registry_json_related): registry = registry_json_related Test = registry.Test Test.insert(properties={'name': 'jssuzanne'}) query = registry.Test.query().filter( Test.name.cast(types.String) == '"jssuzanne"') assert query.count()
class TestMigration: @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="Can't create empty table") def test_add_table(self, registry): registry.migration.table().add('test2') registry.migration.table('test2') def fill_test_table(self, registry): Test = registry.Test vals = [{'other': 'test %d' % x} for x in range(10)] Test.multi_insert(*vals) def test_add_column(self, registry): t = registry.migration.table('test') t.column().add(Column('new_column', Integer)) t.column('new_column') def test_add_column_in_filled_table(self, registry): self.fill_test_table(registry) t = registry.migration.table('test') t.column().add(Column('new_column', Integer)) t.column('new_column') def test_add_not_null_column(self, registry): t = registry.migration.table('test') t.column().add(Column('new_column', Integer, nullable=False)) t.column('new_column') def test_add_not_null_column_in_filled_table(self, registry): self.fill_test_table(registry) t = registry.migration.table('test') t.column().add(Column('new_column', Integer, nullable=False)) t.column('new_column') def test_add_column_with_default_value(self, registry): t = registry.migration.table('test') t.column().add(Column('new_column', Integer, default=100)) t.column('new_column') def test_add_column_with_default_str_value(self, registry): t = registry.migration.table('test') t.column().add(Column('new_column', Integer, default='100')) t.column('new_column') def test_add_column_in_filled_table_with_default_value(self, registry): self.fill_test_table(registry) t = registry.migration.table('test') t.column().add(Column('new_column', Integer, default=100)) t.column('new_column') res = [ x for x in registry.execute( "select count(*) from test where new_column is null") ][0][0] assert res == 0 def test_add_not_null_column_in_filled_table_with_default_value( self, registry): self.fill_test_table(registry) t = registry.migration.table('test') t.column().add( Column('new_column', Integer, nullable=False, server_default="1")) t.column('new_column') def test_add_unique_constraint_on_good_table(self, registry): self.fill_test_table(registry) t = registry.migration.table('test') t.unique('unique_constraint').add(t.column('other')) registry.Test.insert(other='One entry') with pytest.raises(IntegrityError): registry.Test.insert(other='One entry') def test_add_unique_constraint_on_not_unique_column(self, registry): Test = registry.Test vals = [{'other': 'test'} for x in range(10)] Test.multi_insert(*vals) t = registry.migration.table('test') t.unique(None).add(t.column('other')) registry.Test.insert(other='One entry') registry.Test.insert(other='One entry') def test_drop_table(self, registry): registry.migration.table('test').drop() with pytest.raises(MigrationException): registry.migration.table('Test') def test_drop_column(self, registry): t = registry.migration.table('test') t.column('other').drop() with pytest.raises(MigrationException): t.column('other') def test_alter_table_name(self, registry): t = registry.migration.table('test') t.alter(name='othername') registry.migration.table('othername') with pytest.raises(MigrationException): registry.migration.table('test') def test_alter_column_name(self, registry): t = registry.migration.table('test') t.column('other').alter(name='othername') t.column('othername') with pytest.raises(MigrationException): t.column('other') def test_alter_column_nullable(self, registry): t = registry.migration.table('test') c = t.column('other').alter(nullable=False) assert not c.nullable def test_alter_column_nullable_in_filled_table(self, registry): t = registry.migration.table('test') t.column().add(Column('new_column', Integer)) self.fill_test_table(registry) c = t.column('new_column').alter(nullable=False) # the column doesn't change of nullable to not lock the migration assert c.nullable def test_alter_column_default(self, registry): t = registry.migration.table('test') c = t.column('other').alter(server_default='test') if sgdb_in(['PostgreSQL']): assert c.server_default == "'test'::character varying" else: assert str(c.server_default) == "'test'" def test_index(self, registry): t = registry.migration.table('test') t.index().add(t.column('integer')) t.index(t.column('integer')).drop() def test_alter_column_type(self, registry): t = registry.migration.table('test') c = t.column('other').alter(type_=TEXT) assert isinstance(c.type, TEXT) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="Can't drop primary key issue #92") def test_alter_column_primary_key(self, registry): t = registry.migration.table('test') t.primarykey().drop().add(t.column('other')) def test_alter_column_foreign_key(self, registry): t = registry.migration.table('test') t.foreign_key('my_fk').add(['other'], [registry.System.Blok.name]) t.foreign_key('my_fk').drop() def test_constraint_unique(self, registry): t = registry.migration.table('test') t.unique(name='test_unique_constraint').add(t.column('other')) t.unique(name='test_unique_constraint').drop() @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="Can't drop check constraint issue #93") def test_constraint_check(self, registry): t = registry.migration.table('test') Test = registry.Test t.check('test').add(Test.other != 'test') # particuliar case of check constraint t.check('anyblok_ck_test__test').drop() def test_detect_under_noautocommit_flag(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), nullable=False), ) registry.Test.__table__.create(bind=conn) registry.migration.detect_changed() registry.migration.withoutautomigration = True with pytest.raises(MigrationException): registry.migration.detect_changed() def test_detect_column_added(self, registry): # Remove a column on the table force the detection to found new column # which is existing in metadata but not in table with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True)) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add test.other") report.apply_change() report = registry.migration.detect_changed() assert not report.log_has("Add test.other") def test_detect_table_removed(self, registry): with cnx(registry) as conn: Table( 'test2', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), ).create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop Table test2") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop Table test2") def test_detect_table_removed_with_reinit_column(self, registry): with cnx(registry) as conn: Table( 'test2', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), ).create(bind=conn) registry.migration.reinit_tables = True report = registry.migration.detect_changed() assert report.log_has("Drop Table test2") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop Table test2")) def test_detect_table_removed_with_reinit_all(self, registry): with cnx(registry) as conn: Table( 'test2', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), ).create(bind=conn) registry.migration.reinit_all = True report = registry.migration.detect_changed() assert report.log_has("Drop Table test2") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop Table test2")) def test_detect_column_removed(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop Column test.other2") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop Column test.other2") def test_detect_column_removed_with_reinit_column(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), ) registry.Test.__table__.create(bind=conn) registry.migration.reinit_columns = True report = registry.migration.detect_changed() assert report.log_has("Drop Column test.other2") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop Column test.other2")) def test_detect_column_removed_with_reinit_all(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64)), ) registry.Test.__table__.create(bind=conn) registry.migration.reinit_all = True report = registry.migration.detect_changed() assert report.log_has("Drop Column test.other2") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop Column test.other2")) def test_detect_not_nullable_column_removed(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64), nullable=False), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert not (report.log_has("Drop Column test.other2")) assert report.log_has("Drop Column test.other2 (not null)") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop Column test.other2") assert not (report.log_has("Drop Column test.other2 (not null)")) def test_detect_nullable(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), nullable=False), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Alter test.other") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Alter test.other")) def test_detect_m2m_primary_key(self, registry): with cnx(registry) as conn: conn.execute("DROP TABLE reltable") conn.execute("""CREATE TABLE reltable ( idmodel1 INT, idmodel2 INT, FOREIGN KEY (idmodel1) REFERENCES testm2m1 (idmodel1), FOREIGN KEY (idmodel2) REFERENCES testm2m2 (idmodel2) );""") with pytest.raises(MigrationException): registry.migration.detect_changed() def test_detect_server_default(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), server_default='9.99'), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Alter test.other") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Alter test.other")) def test_detect_add_index_constraint(self, registry): with cnx(registry) as conn: registry.TestIndex.__table__.drop(bind=conn) registry.TestIndex.__table__ = Table( 'testindex', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), ) registry.TestIndex.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add index constraint on testindex (other)") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Add index constraint on testindex (other)")) def test_detect_add_column_with_index_constraint(self, registry): with cnx(registry) as conn: registry.TestIndex.__table__.drop(bind=conn) registry.TestIndex.__table__ = Table( 'testindex', MetaData(), Column('integer', Integer, primary_key=True), ) registry.TestIndex.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add testindex.other") assert report.log_has("Add index constraint on testindex (other)") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Add testindex.other")) assert not ( report.log_has("Add index constraint on testindex (other)")) def test_detect_drop_index(self, registry): with cnx(registry) as conn: conn.execute("""CREATE INDEX other_idx ON test (other);""") report = registry.migration.detect_changed() assert report.log_has("Drop index other_idx on test") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop index other_idx on test") def test_detect_drop_anyblok_index(self, registry): with cnx(registry) as conn: conn.execute( """CREATE INDEX anyblok_ix_test__other ON test (other);""") report = registry.migration.detect_changed() assert report.log_has("Drop index anyblok_ix_test__other on test") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Drop index anyblok_ix_test__other on test")) def test_detect_drop_index_with_reinit_indexes(self, registry): with cnx(registry) as conn: conn.execute("""CREATE INDEX other_idx ON test (other);""") registry.migration.reinit_indexes = True report = registry.migration.detect_changed() assert report.log_has("Drop index other_idx on test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop index other_idx on test")) def test_detect_drop_index_with_reinit_all(self, registry): with cnx(registry) as conn: conn.execute("""CREATE INDEX other_idx ON test (other);""") registry.migration.reinit_all = True report = registry.migration.detect_changed() assert report.log_has("Drop index other_idx on test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop index other_idx on test")) def test_detect_type(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Alter test.other") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Alter test.other")) def test_detect_primary_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, nullable=False), Column('other', String(64), primary_key=True), ) registry.Test.__table__.create(bind=conn) with pytest.raises(MigrationException): registry.migration.detect_changed() def test_detect_add_foreign_key(self, registry): with cnx(registry) as conn: registry.TestFK.__table__.drop(bind=conn) registry.TestFK.__table__ = Table( 'testfk', MetaData(), Column('integer', Integer, primary_key=True), Column('other', Integer), ) registry.TestFK.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has( "Add Foreign keys on (testfk.other) => (testfktarget.integer)") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Add Foreign keys on (testfk.other) => (testfktarget.integer)")) def test_detect_foreign_key_options_changed(self, registry): with cnx(registry) as conn: registry.TestFK2.__table__.drop(bind=conn) meta = MetaData() meta._add_table('testfktarget', None, registry.TestFKTarget.__table__) registry.TestFK2.__table__ = Table( 'testfk2', meta, Column('integer', Integer, primary_key=True), Column('other', Integer, ForeignKey('testfktarget.integer')), ) registry.TestFK2.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has( "Drop Foreign keys on testfk2.other => testfktarget.integer") assert report.log_has( "Add Foreign keys on (testfk2.other) => (testfktarget.integer)") def test_detect_drop_foreign_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData() meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64), ForeignKey('system_blok.name')), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has( "Drop Foreign keys on test.other => system_blok.name") report.apply_change() report = registry.migration.detect_changed() assert report.log_has( "Drop Foreign keys on test.other => system_blok.name") def test_detect_drop_anyblok_foreign_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData(naming_convention=naming_convention) meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64), ForeignKey('system_blok.name')), ) registry.Test.__table__.create(bind=conn) # anyblok_fk_test__other_on_system_blok__name report = registry.migration.detect_changed() assert report.log_has( "Drop Foreign keys on test.other => system_blok.name") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Drop Foreign keys on test.other => system_blok.name")) def test_detect_drop_foreign_key_with_reinit_constraint(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData() meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64), ForeignKey('system_blok.name')), ) registry.Test.__table__.create(bind=conn) registry.migration.reinit_constraints = True report = registry.migration.detect_changed() assert report.log_has( "Drop Foreign keys on test.other => system_blok.name") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Drop Foreign keys on test.other => system_blok.name")) def test_detect_drop_foreign_key_with_reinit_all(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData() meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64), ForeignKey('system_blok.name')), ) registry.Test.__table__.create(bind=conn) registry.migration.reinit_all = True report = registry.migration.detect_changed() assert report.log_has( "Drop Foreign keys on test.other => system_blok.name") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Drop Foreign keys on test.other => system_blok.name")) def test_detect_drop_column_with_foreign_key(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) meta = MetaData(naming_convention=naming_convention) meta._add_table('system_blok', None, registry.System.Blok.__table__) registry.Test.__table__ = Table( 'test', meta, Column('integer', Integer, primary_key=True), Column('other', String(64)), Column('other2', String(64), ForeignKey('system_blok.name')), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has( "Drop Foreign keys on test.other2 => system_blok.name") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Drop Foreign keys on test.other2 => system_blok.name")) def test_detect_add_unique_constraint(self, registry): with cnx(registry) as conn: registry.TestUnique.__table__.drop(bind=conn) registry.TestUnique.__table__ = Table( 'testunique', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64)), ) registry.TestUnique.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add unique constraint on testunique (other)") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Add unique constraint on testunique (other)")) def test_detect_add_column_with_unique_constraint(self, registry): with cnx(registry) as conn: registry.TestUnique.__table__.drop(bind=conn) registry.TestUnique.__table__ = Table( 'testunique', MetaData(), Column('integer', Integer, primary_key=True), ) registry.TestUnique.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Add unique constraint on testunique (other)") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Add unique constraint on testunique (other)")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="MySQL transform unique constraint on index") def test_detect_drop_unique_constraint(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), unique=True), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop constraint test_other_key on test") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop constraint test_other_key on test") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="MySQL transform unique constraint on index") def test_detect_drop_unique_anyblok_constraint(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), Column('other', String(64), unique=True), ) registry.Test.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has("Drop constraint anyblok_uq_test__other on test") report.apply_change() report = registry.migration.detect_changed() assert not ( report.log_has("Drop constraint anyblok_uq_test__other on test")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="MySQL transform unique constraint on index") def test_detect_drop_unique_constraint_with_reinit_constraints( self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), unique=True), ) registry.Test.__table__.create(bind=conn) registry.migration.reinit_constraints = True report = registry.migration.detect_changed() assert report.log_has("Drop constraint test_other_key on test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop constraint test_other_key on test")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="MySQL transform unique constraint on index") def test_detect_drop_unique_constraint_with_reinit_all(self, registry): with cnx(registry) as conn: registry.Test.__table__.drop(bind=conn) registry.Test.__table__ = Table( 'test', MetaData(), Column('integer', Integer, primary_key=True), Column('other', String(64), unique=True), ) registry.Test.__table__.create(bind=conn) registry.migration.reinit_all = True report = registry.migration.detect_changed() assert report.log_has("Drop constraint test_other_key on test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop constraint test_other_key on test")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="No CheckConstraint works #90") def test_no_detect_drop_and_add_check_constraint_with_long_name( self, registry): report = registry.migration.detect_changed() assert not (report.log_has( "Drop check constraint anyblok_ck_testchecklongconstraintname" "__long_long_long_long_lon on testchecklongconstraintname")) assert not (report.log_has( "Add check constraint anyblok_ck_testchecklongconstraintname__" "long_long_long_long_long_long_long_long_long_long_long_long_" "long_long_long_long_long_long_test on " "testchecklongconstraintname")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="No CheckConstraint works #90") def test_detect_add_check_constraint(self, registry): with cnx(registry) as conn: registry.TestCheck.__table__.drop(bind=conn) registry.TestCheck.__table__ = Table( 'testcheck', MetaData(naming_convention=naming_convention), Column('integer', Integer, primary_key=True), ) registry.TestCheck.__table__.create(bind=conn) report = registry.migration.detect_changed() assert report.log_has( "Add check constraint anyblok_ck_testcheck__test on testcheck") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Add check constraint anyblok_ck_testcheck__test on testcheck")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="No CheckConstraint works #90") def test_detect_drop_check_constraint(self, registry): with cnx(registry) as conn: conn.execute("DROP TABLE test") conn.execute("""CREATE TABLE test( integer INT PRIMARY KEY NOT NULL, other CHAR(64) CONSTRAINT ck_other CHECK (other != 'test') );""") report = registry.migration.detect_changed() assert report.log_has("Drop check constraint ck_other on test") report.apply_change() report = registry.migration.detect_changed() assert report.log_has("Drop check constraint ck_other on test") @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="No CheckConstraint works #90") def test_detect_drop_check_anyblok_constraint(self, registry): with cnx(registry) as conn: conn.execute("DROP TABLE test") conn.execute("""CREATE TABLE test( integer INT PRIMARY KEY NOT NULL, other CHAR(64) CONSTRAINT anyblok_ck__test__check CHECK (other != 'test') );""") report = registry.migration.detect_changed() assert report.log_has( "Drop check constraint anyblok_ck__test__check on test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has( "Drop check constraint anyblok_ck__test__check on test")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="No CheckConstraint works #90") def test_detect_drop_check_constraint_with_reinit_constraint( self, registry): with cnx(registry) as conn: conn.execute("DROP TABLE test") conn.execute("""CREATE TABLE test( integer INT PRIMARY KEY NOT NULL, other CHAR(64) CONSTRAINT ck_other CHECK (other != 'test') );""") registry.migration.reinit_constraints = True report = registry.migration.detect_changed() assert report.log_has("Drop check constraint ck_other on test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop check constraint ck_other on test")) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason="No CheckConstraint works #90") def test_detect_drop_check_constraint_with_reinit_all(self, registry): with cnx(registry) as conn: conn.execute("DROP TABLE test") conn.execute("""CREATE TABLE test( integer INT PRIMARY KEY NOT NULL, other CHAR(64) CONSTRAINT ck_other CHECK (other != 'test') );""") registry.migration.reinit_all = True report = registry.migration.detect_changed() assert report.log_has("Drop check constraint ck_other on test") report.apply_change() report = registry.migration.detect_changed() assert not (report.log_has("Drop check constraint ck_other on test")) def test_savepoint(self, registry): Test = registry.Test self.fill_test_table(registry) registry.migration.savepoint('test') self.fill_test_table(registry) assert Test.query().count() == 20 registry.migration.rollback_savepoint('test') assert Test.query().count() == 10 registry.migration.release_savepoint('test') def test_savepoint_without_rollback(self, registry): registry.migration.savepoint('test') registry.migration.release_savepoint('test') with pytest.raises((InternalError, OperationalError)): registry.migration.rollback_savepoint('test')
class TestMany2OneOld: @pytest.fixture(autouse=True) def close_registry(self, request, bloks_loaded): def close(): if hasattr(self, 'registry'): self.registry.close() request.addfinalizer(close) def init_registry(self, *args, **kwargs): reset_db() self.registry = init_registry(*args, **kwargs) return self.registry def test_2_many2one(self): with pytest.raises(FieldException): self.init_registry(_many2one_with_same_name_for_column_names) @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason='ISSUE #89') def test_minimum_many2one_on_sequence(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) seq = Sequence(primary_key=True, formater="V-{seq}") @register(Model) class Test2: seq = Sequence(primary_key=True) test = Many2One(model=Model.Test) registry = self.init_registry(add_in_registry) test = registry.Test.insert() test2 = registry.Test2.insert(test=test) assert test is test2.test def test_minimum_many2one_without_model(self): with pytest.raises(FieldException): self.init_registry(_minimum_many2one_without_model) def test_same_model(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) parent = Many2One(model='Model.Test', one2many='children') registry = self.init_registry(add_in_registry) t1 = registry.Test.insert() t2 = registry.Test.insert(parent=t1) assert t2.parent is t1 assert t1.children[0] is t2 def test_same_model_pk_by_inherit(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) @register(Model) # noqa class Test: parent = Many2One(model='Model.Test', one2many='children') registry = self.init_registry(add_in_registry) t1 = registry.Test.insert() t2 = registry.Test.insert(parent=t1) assert t2.parent is t1 assert t1.children[0] is t2 def test_same_model_pk_by_mixin(self): def add_in_registry(): @register(Mixin) class MTest: id = Integer(primary_key=True) @register(Model) # noqa class Test(Mixin.MTest): parent = Many2One(model='Model.Test', one2many='children') registry = self.init_registry(add_in_registry) t1 = registry.Test.insert() t2 = registry.Test.insert(parent=t1) assert t2.parent is t1 assert t1.children[0] is t2 def test_add_unique_constraint(self): def add_in_registry(): @register(Model) class Address: id = Integer(primary_key=True) @register(Model) class Person: name = String(primary_key=True) address = Many2One(model=Model.Address, unique=True) registry = self.init_registry(add_in_registry) address = registry.Address.insert() registry.Person.insert( name="Jean-sébastien SUZANNE", address=address) with pytest.raises(IntegrityError): registry.Person.insert(name="Other", address=address) def test_add_index_constraint(self): def add_in_registry(): @register(Model) class Address: id = Integer(primary_key=True) @register(Model) class Person: name = String(primary_key=True) address = Many2One(model=Model.Address, index=True) registry = self.init_registry(add_in_registry) inspector = Inspector(registry.session.connection()) indexes = inspector.get_indexes(registry.Person.__tablename__) assert len(indexes) == 1 def test_add_primary_keys_constraint(self): def add_in_registry(): @register(Model) class Address: id = Integer(primary_key=True) @register(Model) class Person: name = String(primary_key=True) address = Many2One(model=Model.Address, primary_key=True) registry = self.init_registry(add_in_registry) inspector = Inspector(registry.session.connection()) pks = inspector.get_primary_keys(registry.Person.__tablename__) assert 'address_id'in pks def test_complet_with_multi_foreign_key(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True, unique=True) id2 = String(primary_key=True, unique=True) @register(Model) class Test2: @classmethod def define_table_args(cls): table_args = super(Test2, cls).define_table_args() return table_args + (ForeignKeyConstraint( [cls.test_id, cls.test_id2], ['test.id', 'test.id2']),) id = Integer(primary_key=True) test_id = Integer( foreign_key=Model.Test.use('id'), nullable=False) test_id2 = String( foreign_key=Model.Test.use('id2'), nullable=False) test = Many2One(model=Model.Test, remote_columns=('id', 'id2'), column_names=('test_id', 'test_id2')) registry = self.init_registry(add_in_registry) test = registry.Test.insert(id2="10") test2 = registry.Test2.insert(test=test) assert test.id == test2.test_id assert test.id2 is test2.test_id2 def test_complet_with_multi_foreign_key_without_constraint(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True, unique=True) id2 = String(primary_key=True, unique=True) @register(Model) class Test2: id = Integer(primary_key=True) test_id = Integer( foreign_key=Model.Test.use('id'), nullable=False) test_id2 = String( foreign_key=Model.Test.use('id2'), nullable=False) test = Many2One(model=Model.Test, remote_columns=('id', 'id2'), column_names=('test_id', 'test_id2')) registry = self.init_registry(add_in_registry) test = registry.Test.insert(id2="10") test2 = registry.Test2.insert(test=test) assert test.id == test2.test_id assert test.id2 is test2.test_id2 def test_with_multi_foreign_key_on_existing_column(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True, unique=True) id2 = String(primary_key=True, unique=True) @register(Model) class Test2: id = Integer(primary_key=True) test_id = Integer( foreign_key=Model.Test.use('id'), nullable=False) test_id2 = String( foreign_key=Model.Test.use('id2'), nullable=False) test = Many2One(model=Model.Test) registry = self.init_registry(add_in_registry) test = registry.Test.insert(id2="10") test2 = registry.Test2.insert(test=test) assert test.id == test2.test_id assert test.id2 is test2.test_id2 def test_with_multi_foreign_key_on_existing_column2(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True, unique=True) id2 = String(primary_key=True, unique=True) @register(Model) class Test2: id = Integer(primary_key=True) other_test_id = Integer( foreign_key=Model.Test.use('id'), nullable=False) other_test_id2 = String( foreign_key=Model.Test.use('id2'), nullable=False) test = Many2One(model=Model.Test) registry = self.init_registry(add_in_registry) test = registry.Test.insert(id2="10") test2 = registry.Test2.insert(test=test) assert test.id == test2.other_test_id assert test.id2 is test2.other_test_id2 def test_with_multi_foreign_key_on_unexisting_column(self): registry = self.init_registry(_two_remote_primary_keys) test = registry.Test.insert(id2="10") test2 = registry.Test2.insert(test=test) assert test.id == test2.test_id assert test.id2 is test2.test_id2 def test_many2one_with_multi_fk_expire_field(self): registry = self.init_registry(_two_remote_primary_keys) assert('test',) in registry.expire_attributes['Model.Test2']['test_id'] assert ('test',) in registry.expire_attributes[ 'Model.Test2']['test_id2'] def test_with_multi_foreign_key_on_unexisting_named_column(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True, unique=True) id2 = String(primary_key=True, unique=True) @register(Model) class Test2: id = Integer(primary_key=True) test = Many2One(model=Model.Test, column_names=('test_id', 'test_id2')) registry = self.init_registry(add_in_registry) test = registry.Test.insert(id2="10") test2 = registry.Test2.insert(test=test) assert test.id == test2.test_id assert test.id2 is test2.test_id2 def test_with_multi_foreign_key_on_unexisting_named_column2(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True, unique=True) id2 = Integer(primary_key=True, unique=True) @register(Model) class Test2: id = Integer(primary_key=True) test = Many2One(model=Model.Test, column_names=( 'other_test_id', 'other_test_id2')) with pytest.raises(FieldException): self.init_registry(add_in_registry) def test_m2o_in_mixin(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) @register(Mixin) class MTest: test = Many2One(model=Model.Test) @register(Model) class Test1(Mixin.MTest): id = Integer(primary_key=True) @register(Model) class Test2(Mixin.MTest): id = Integer(primary_key=True) registry = self.init_registry(add_in_registry) test = registry.Test.insert() test1 = registry.Test1.insert(test=test) test2 = registry.Test2.insert(test=test) assert test1.test_id == test2.test_id def test_delete_m2o_without_fk_options_on_delete_cascade(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) @register(Model) class TestM2O: id = Integer(primary_key=True) test = Many2One(model=Model.Test, nullable=True) registry = self.init_registry(add_in_registry) test = registry.Test.insert() testM2O = registry.TestM2O.insert(test=test) assert testM2O.test is test with pytest.raises(IntegrityError): test.delete() def test_delete_m2o_with_fk_options_on_delete_cascade(self): def add_in_registry(): @register(Model) class Test: id = Integer(primary_key=True) @register(Model) class TestM2O: id = Integer(primary_key=True) test = Many2One(model=Model.Test, nullable=True, foreign_key_options={'ondelete': 'cascade'}) registry = self.init_registry(add_in_registry) test = registry.Test.insert() testM2O = registry.TestM2O.insert(test=test) assert testM2O.test is test test.delete() assert not (registry.TestM2O.query().count()) def test_2_simple_many2one_on_the_same_model(self): def add_in_registry(): @register(Model) class Address: id = Integer(primary_key=True) @register(Model) class Person: name = String(primary_key=True) address_1 = Many2One(model=Model.Address) address_2 = Many2One(model=Model.Address) registry = self.init_registry(add_in_registry) address_1 = registry.Address.insert() address_2 = registry.Address.insert() person = registry.Person.insert( name='test', address_1=address_1, address_2=address_2) assert person.address_1 is address_1 assert person.address_2 is address_2 assert person.address_1 is not person.address_2
def add_in_registry(): register = Declarations.register Model = Declarations.Model @register(Model) class Test: integer = Int(primary_key=True) other = Str() @register(Model) class TestUnique: integer = Int(primary_key=True) other = Str(unique=True) @register(Model) class TestIndex: integer = Int(primary_key=True) other = Str(index=True) if not sgdb_in(['MySQL', 'MariaDB']): @register(Model) class TestCheck: integer = Int(primary_key=True) @classmethod def define_table_args(cls): table_args = super(TestCheck, cls).define_table_args() return table_args + (CheckConstraint('integer > 0', name='test'), ) @register(Model) class TestCheckLongConstraintName: integer = Int(primary_key=True) @classmethod def define_table_args(cls): table_args = super(TestCheckLongConstraintName, cls).define_table_args() return table_args + (CheckConstraint( 'integer > 0', name=('long_long_long_long_long_long_long_long_long_long_' 'long_long_long_long_long_long_long_long_test')), ) @register(Model) class TestFKTarget: integer = Int(primary_key=True) @register(Model) class TestFK: integer = Int(primary_key=True) other = Int(foreign_key=Model.TestFKTarget.use('integer')) @register(Model) class TestFK2: integer = Int(primary_key=True) other = Int(foreign_key=Model.TestFKTarget.use('integer').options( ondelete='cascade')) @register(Model) class TestM2M1: idmodel1 = Int(primary_key=True) @register(Model) class TestM2M2: idmodel2 = Int(primary_key=True) rel_m2m = Many2Many(label="Rel", model=Model.TestM2M1, join_table='reltable', remote_columns='idmodel1', m2m_remote_columns='idmodel1', local_columns='idmodel2', m2m_local_columns='idmodel2', many2many='rel_m2m_inv')
class TestMigrationPlugin: @pytest.mark.skipif(not sgdb_in(['MySQL', 'MariaDB']), reason='Plugin for MySQL only') def test_boolean_with_mysql(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) res = report.init_modify_type( [None, None, 'test', 'other', {}, TINYINT(), Boolean()]) assert res is True @pytest.mark.skipif(not sgdb_in(['MySQL', 'MariaDB']), reason='Plugin for MySQL only') def test_datetime_with_mysql(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) res = report.init_modify_type( [None, None, 'test', 'other', {}, DATETIME(), DATETIME()]) assert res is True @pytest.mark.skipif(not sgdb_in(['MsSQL']), reason='Plugin for MsSQL only') def test_boolean_with_mssql(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) res = report.init_modify_type( [None, None, 'test', 'other', {}, BIT(), Boolean()]) assert res is True @pytest.mark.skipif(not sgdb_in(['PostgreSQL']), reason='Plugin for MsSQL only') def test_boolean_with_postgres(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) res = report.init_modify_type( [None, None, 'test', 'other', {}, Integer(), Boolean()]) assert res is False def test_alter_column_type_with_plugin_1(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) report.plugins = [ MockMigrationColumnTypePluginInteger2String, ] with patch('anyblok.tests.test_migration.' 'MockMigrationColumnTypePluginInteger2String.apply' ) as mockapply: report.apply_change_modify_type( [None, None, 'test', 'other', {}, Integer(), String()]) mockapply.assert_called() def test_alter_column_type_with_plugin_2(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) report.plugins = [ MockMigrationColumnTypePluginInteger2String, ] with patch('anyblok.migration.MigrationColumn.alter') as mockapply: report.apply_change_modify_type( [None, None, 'test', 'other', {}, String(), Integer()]) mockapply.assert_called() @pytest.mark.skipif(not sgdb_in(['MySQL', 'MariaDB']), reason='Plugin for MySQL only') def test_alter_column_type_with_plugin_3(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) report.plugins = [ MockMigrationColumnTypePluginInteger2StringMySQL, ] with patch('anyblok.tests.test_migration.' 'MockMigrationColumnTypePluginInteger2StringMySQL.apply' ) as mockapply: report.apply_change_modify_type( [None, None, 'test', 'other', {}, Integer(), String()]) mockapply.assert_called() @pytest.mark.skipif(sgdb_in(['MySQL', 'MariaDB']), reason='Plugin for MySQL only') def test_alter_column_type_with_plugin_4(self, registry_plugin): report = MigrationReport(registry_plugin.migration, []) report.plugins = [ MockMigrationColumnTypePluginInteger2StringMySQL, ] with patch('anyblok.migration.MigrationColumn.alter') as mockapply: report.apply_change_modify_type( [None, None, 'test', 'other', {}, Integer(), String()]) mockapply.assert_called()