def fail_with_transaction_error(cls): """ Just fail raising a DatabaseOperationalError """ from trytond import backend DatabaseOperationalError = backend.get('DatabaseOperationalError') raise DatabaseOperationalError()
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') super(Location, cls).__register__(module_name) cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) table.index_action(['left', 'right'], 'add')
def __register__(cls, z_fix__invoice_ar__sale_pos): #super(AfipWSTransaction, cls).__register__(z_fix__invoice_ar__sale_pos) TableHandler = backend.get('TableHandler') cursor = Transaction().cursor table = TableHandler(cursor, cls, z_fix__invoice_ar__sale_pos) cursor.execute("ALTER TABLE account_invoice_ar_afip_transaction\ DROP CONSTRAINT IF EXISTS account_invoice_ar_afip_transaction_invoice_fkey;")
def __register__(cls, module_name): pool = Pool() Account = pool.get('analytic_account.account') TableHandler = backend.get('TableHandler') cursor = Transaction().cursor # Migration from 3.4: use origin as the key for One2Many migration_3_4 = False old_table = 'analytic_account_account_selection_rel' if TableHandler.table_exist(cursor, old_table): TableHandler.table_rename(cursor, old_table, cls._table) migration_3_4 = True # Don't create table before renaming table = TableHandler(cursor, cls, module_name) super(AnalyticAccountEntry, cls).__register__(module_name) # Migration from 3.4: set root value and remove required if migration_3_4: account = Account.__table__() cursor.execute(*account.select(account.id, account.root, where=account.type != 'root')) entry = cls.__table__() for account_id, root_id in cursor.fetchall(): cursor.execute(*entry.update( columns=[entry.root], values=[root_id], where=entry.account == account_id)) table.not_null_action('selection', action='remove') table.not_null_action('account', action='remove')
def __register__(cls, module_name): pool = Pool() Party = pool.get('party.party') TableHandler = backend.get('TableHandler') cursor = Transaction().cursor party = Party.__table__() super(PartyIdentifier, cls).__register__(module_name) party_h = TableHandler(cursor, Party, module_name) if (party_h.column_exist('vat_number') and party_h.column_exist('vat_country')): identifiers = [] cursor.execute(*party.select( party.id, party.vat_number, party.vat_country, where=(party.vat_number != Null) | (party.vat_country != Null))) for party_id, number, country in cursor.fetchall(): code = (country or '') + (number or '') if not code: continue type = None if vat.is_valid(code): type = 'eu_vat' identifiers.append( cls(party=party_id, code=code, type=type)) cls.save(identifiers) party_h.drop_column('vat_number') party_h.drop_column('vat_country')
def __register__(cls, module_name): pool = Pool() Employee = pool.get('company.employee') TableHandler = backend.get('TableHandler') cursor = Transaction().cursor table = cls.__table__() table_h = TableHandler(cursor, cls, module_name) migrate_cost_price = not table_h.column_exist('cost_price') super(TimesheetLine, cls).__register__(module_name) # Migration from 3.6: add cost_price if migrate_cost_price: cursor.execute(*table.select(table.id, table.employee, table.date, where=(table.cost_price == 0) & (table.employee != Null) & (table.date != Null))) for line_id, employee_id, date in cursor.fetchall(): employee = Employee(employee_id) cost_price = employee.compute_cost_price(date=date) cursor.execute(*table.update( [table.cost_price], [cost_price], where=table.id == line_id))
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() pool = Pool() Line = pool.get('account.invoice.payment_term.line') sql_table = cls.__table__() line = Line.__table__() # Migration from 4.0: rename long table old_model_name = 'account.invoice.payment_term.line.relativedelta' old_table = config.get( 'table', old_model_name, default=old_model_name.replace('.', '_')) if TableHandler.table_exist(old_table): TableHandler.table_rename(old_table, cls._table) super(PaymentTermLineRelativeDelta, cls).__register__(module_name) line_table = Line.__table_handler__(module_name) # Migration from 3.4 fields = ['day', 'month', 'weekday', 'months', 'weeks', 'days'] if any(line_table.column_exist(f) for f in fields): columns = ([line.id.as_('line')] + [Column(line, f) for f in fields]) cursor.execute(*sql_table.insert( columns=[sql_table.line] + [Column(sql_table, f) for f in fields], values=line.select(*columns))) for field in fields: line_table.drop_column(field)
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) sql_table = cls.__table__() pool = Pool() Work = pool.get('timesheet.work') work = Work.__table__() created_company = not table.column_exist('company') super(Line, cls).__register__(module_name) table = TableHandler(cursor, cls, module_name) # Migration from 3.4: new company field if created_company: # Don't use FROM because SQLite nor MySQL support it. cursor.execute(*sql_table.update( [sql_table.company], [work.select(work.company, where=work.id == sql_table.work)])) # Migration from 3.4: change hours into timedelta duration if table.column_exist('hours'): table.drop_constraint('check_move_hours_pos') cursor.execute(*sql_table.select( sql_table.id, sql_table.hours)) for id_, hours in cursor.fetchall(): duration = datetime.timedelta(hours=hours) cursor.execute(*sql_table.update( [sql_table.duration], [duration], where=sql_table.id == id_)) table.drop_column('hours')
def run(self): from trytond.config import CONFIG CONFIG['db_type'] = 'postgresql' CONFIG['db_host'] = 'localhost' CONFIG['db_port'] = 5432 CONFIG['db_user'] = '******' CONFIG['timezone'] = 'UTC' from trytond import backend import trytond.tests.test_tryton # Set the db_type again because test_tryton writes this to sqlite # again CONFIG['db_type'] = 'postgresql' trytond.tests.test_tryton.DB_NAME = 'test_' + str(int(time.time())) from trytond.tests.test_tryton import DB_NAME trytond.tests.test_tryton.DB = backend.get('Database')(DB_NAME) from trytond.pool import Pool Pool.test = True trytond.tests.test_tryton.POOL = Pool(DB_NAME) from tests import suite test_result = unittest.TextTestRunner(verbosity=3).run(suite()) if test_result.wasSuccessful(): sys.exit(0) sys.exit(-1)
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor sql_table = cls.__table__() # Migration from 1.8: new field company table = TableHandler(cursor, cls, module_name) company_exist = table.column_exist('company') super(Statement, cls).__register__(module_name) # Migration from 1.8: fill new field company if not company_exist: offset = 0 limit = cursor.IN_MAX statements = True while statements: statements = cls.search([], offset=offset, limit=limit) offset += limit for statement in statements: cls.write([statement], { 'company': statement.journal.company.id, }) table = TableHandler(cursor, cls, module_name) table.not_null_action('company', action='add') # Migration from 3.2: remove required on start/end balance table.not_null_action('start_balance', action='remove') table.not_null_action('end_balance', action='remove') # Migration from 3.2: add required name cursor.execute(*sql_table.update([sql_table.name], [sql_table.id.cast(cls.name.sql_type().base)], where=sql_table.name == None))
def db_exist(request, database_name): Database = backend.get('Database') try: Database(database_name).connect() return True except Exception: return False
def restore_default_party_lang_from_4_2(cls): from trytond.transaction import Transaction from sql import Null, Table, Cast from sql.operators import Concat from trytond.pool import Pool TableHandler = backend.get('TableHandler') if not TableHandler.table_exist('ir_property'): return pool = Pool() property = Table('ir_property') Lang = pool.get('ir.lang') field = pool.get('ir.model.field').__table__() lang = Lang.__table__() cursor = Transaction().connection.cursor() query_table = property.join(lang, condition=( property.value == Concat('ir.lang,', Cast(lang.id, 'VARCHAR')) )).join(field, condition=((property.field == field.id) & (field.name == 'lang'))) cursor.execute( *query_table.select(lang.id, where=property.res == Null)) result = cursor.fetchone() if result: result = list(result) default_lang = Lang(result[0]) print('Default Language restored [%s]' % default_lang.rec_name) pool.get('party.configuration.party_lang' ).create([{'party_lang': default_lang}]) else: print('No default language on party configuration found')
def __register__(cls, module_name): TableHandler = backend.get("TableHandler") super(Location, cls).__register__(module_name) cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) table.index_action(["left", "right"], "add")
def login(request, database_name, user, password): Database = backend.get('Database') DatabaseOperationalError = backend.get('DatabaseOperationalError') try: Database(database_name).connect() except DatabaseOperationalError: logger.error('fail to connect to %s', database_name, exc_info=True) return False session = security.login(database_name, user, password) with Transaction().start(database_name, 0): Cache.clean(database_name) Cache.resets(database_name) msg = 'successful login' if session else 'bad login or password' logger.info('%s \'%s\' from %s using %s on database \'%s\'', msg, user, request.remote_addr, request.scheme, database_name) return session
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor sql_table = cls.__table__() table = TableHandler(cursor, cls, module_name) if not table.column_exist('shop'): table.add_raw_column( 'shop', cls.shop.sql_type(), cls.shop.sql_format, None, None ) else: Shop = Pool().get('sale.shop') shops = Shop.search([]) if shops: sales = cls.search([ ('shop', '=', None), ]) for sale in sales: cursor.execute(*sql_table.update( columns=[sql_table.shop], values=[shops[0].id], where=sql_table.id == sale.id)) else: logging.getLogger('sale shop').warning( 'You must to create a shop and update module ' 'to assign current sales to new shop.') super(Sale, cls).__register__(module_name)
def db_exist(): Database = backend.get('Database') database = Database().connect() cursor = database.cursor() databases = database.list(cursor) cursor.close() return DB_NAME in databases
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) sql_table = cls.__table__() # Migration from 2.2 new field currency created_currency = table.column_exist('currency') super(ProductSupplier, cls).__register__(module_name) # Migration from 2.2 fill currency if not created_currency: Company = Pool().get('company.company') company = Company.__table__() limit = cursor.IN_MAX cursor.execute(*sql_table.select(Count(sql_table.id))) product_supplier_count, = cursor.fetchone() for offset in range(0, product_supplier_count, limit): cursor.execute(*sql_table.join(company, condition=sql_table.company == company.id ).select(sql_table.id, company.currency, order_by=sql_table.id, limit=limit, offset=offset)) for product_supplier_id, currency_id in cursor.fetchall(): cursor.execute(*sql_table.update( columns=[sql_table.currency], values=[currency_id], where=sql_table.id == product_supplier_id)) # Migration from 2.4: drop required on sequence table.not_null_action('sequence', action='remove') # Migration from 2.6: drop required on delivery_time table.not_null_action('delivery_time', action='remove')
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor super(ProductMedia, cls).__register__(module_name) media_table = cls.__table__() if TableHandler.table_exist(cursor, 'product_product_imageset'): # Migrate data from ProductImageSet table to ProductMedia table imageset_table = Table('product_product_imageset') cursor.execute(*media_table.insert( columns=[ media_table.sequence, media_table.product, media_table.template, media_table.static_file, ], values=imageset_table.select( Literal(10), imageset_table.product, imageset_table.template, imageset_table.image ) )) TableHandler.drop_table( cursor, 'product.product.imageset', 'product_product_imageset', cascade=True )
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') sql_table = cls.__table__() super(PaymentTermLine, cls).__register__(module_name) cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) # Migration from 1.0 percent change into percentage if table.column_exist('percent'): cursor.execute(*sql_table.update( columns=[sql_table.percentage], values=[sql_table.percent * 100])) table.drop_column('percent', exception=True) # Migration from 2.2 if table.column_exist('delay'): cursor.execute(*sql_table.update( columns=[sql_table.day], values=[31], where=sql_table.delay == 'end_month')) table.drop_column('delay', exception=True) lines = cls.search([]) for line in lines: if line.percentage: cls.write([line], { 'divisor': cls.round(Decimal('100.0') / line.percentage, cls.divisor.digits[1]), }) # Migration from 2.4: drop required on sequence table.not_null_action('sequence', action='remove')
def get_userinfo(self, user, password, command=''): path = urlparse.urlparse(self.path).path dbname = urllib.unquote_plus(path.split('/', 2)[1]) database = backend.get('Database')().connect() cursor = database.cursor() databases = database.list(cursor) cursor.close() if not dbname or dbname not in databases: return True if user: user = int(login(dbname, user, password, cache=False)) if not user: return None else: url = urlparse.urlparse(self.path) query = urlparse.parse_qs(url.query) path = url.path[len(dbname) + 2:] if 'key' in query: key, = query['key'] with Transaction().start(dbname, 0) as transaction: database_list = Pool.database_list() pool = Pool(dbname) if dbname not in database_list: pool.init() Share = pool.get('webdav.share') user = Share.get_login(key, command, path) transaction.cursor.commit() if not user: return None Transaction().start(dbname, user, context={ '_check_access': True, }, autocommit=True) Cache.clean(dbname) return user
def get_childs(self, uri, filter=None): res = [] dbname, dburi = self._get_dburi(uri) if not dbname: database = backend.get('Database')().connect() cursor = database.cursor() try: lists = database.list(cursor) except Exception: lists = [] finally: cursor.close() for dbname in lists: res.append(urlparse.urljoin(uri, dbname)) return res pool = Pool(Transaction().cursor.database_name) try: Collection = pool.get('webdav.collection') scheme, netloc, path, params, query, fragment = \ urlparse.urlparse(uri) if path[-1:] != '/': path += '/' for child in Collection.get_childs(dburi, filter=filter, cache=CACHE): res.append(urlparse.urlunparse((scheme, netloc, path + child.encode('utf-8'), params, query, fragment))) except KeyError: return res except (DAV_Error, DAV_NotFound, DAV_Secret, DAV_Forbidden), exception: self._log_exception(exception) raise
def start(self, database_name, user, readonly=False, context=None, close=False, autocommit=False): ''' Start transaction ''' Database = backend.get('Database') assert self.user is None assert self.database is None assert self.close is None assert self.context is None if not database_name: database = Database().connect() else: database = Database(database_name).connect() Flavor.set(Database.flavor) self.user = user self.database = database self.readonly = readonly self.connection = database.get_connection(readonly=readonly, autocommit=autocommit) self.close = close self.context = context or {} self.create_records = {} self.delete_records = {} self.delete = {} self.timestamp = {} self.counter = 0 self._datamanagers = [] return self
def __register__(cls, module_name): pool = Pool() ProductCostPrice = pool.get('product.cost_price') TableHandler = backend.get('TableHandler') sql_table = cls.__table__() cost_price = ProductCostPrice.__table__() cursor = Transaction().connection.cursor() exist = TableHandler.table_exist(cls._table) cost_price_exist = TableHandler.table_exist(ProductCostPrice._table) super(ProductCostPriceMethod, cls).__register__(module_name) # Migrate from 4.4: move cost_price_method from ProductCostPrice if not exist and not cost_price_exist: cls._migrate_property([], [], []) elif not exist and cost_price_exist: cost_price_table = TableHandler(ProductCostPrice, module_name) if cost_price_table.column_exist('template'): columns = ['create_uid', 'create_date', 'write_uid', 'write_date', 'template', 'cost_price_method'] cursor.execute(*sql_table.insert( columns=[Column(sql_table, c) for c in columns], values=cost_price.select( *[Column(cost_price, c) for c in columns])))
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor super(EmployeeCostPrice, cls).__register__(module_name) table = TableHandler(cursor, cls, module_name) # Migration from 2.8 drop date_cost_price_uniq table.drop_constraint('date_cost_price_uniq')
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') exist = TableHandler.table_exist(cls._table) super(ConfigurationPos, cls).__register__(module_name) if not exist: cls._migrate_property([], [], [])
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') exist = TableHandler.table_exist(cls._table) super(ProductListPrice, cls).__register__(module_name) if not exist: cls._migrate_property([], [], [])
def __register__(cls, module_name): TableHandler = backend.get("TableHandler") cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) table.column_rename("folder_name", "name") super(NereidStaticFolder, cls).__register__(module_name)
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') super(Line, cls).__register__(module_name) cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) # Migration from 1.2 currency has been changed in function field table.not_null_action('currency', action='remove')
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') super(Inventory, cls).__register__(module_name) cursor = Transaction().cursor # Add index on create_date table = TableHandler(cursor, cls, module_name) table.index_action('create_date', action='add')
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor # Migration from 2.2 table = TableHandler(cursor, cls, module_name) table.drop_constraint('check_min_max_quantity') super(OrderPoint, cls).__register__(module_name)
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') sql_table = cls.__table__() super(PaymentTermLine, cls).__register__(module_name) cursor = Transaction().connection.cursor() table = TableHandler(cls, module_name) # Migration from 1.0 percent change into percentage if table.column_exist('percent'): cursor.execute(*sql_table.update( columns=[sql_table.percentage], values=[sql_table.percent * 100])) table.drop_column('percent', exception=True) # Migration from 2.2 if table.column_exist('delay'): cursor.execute(*sql_table.update( columns=[sql_table.day], values=[31], where=sql_table.delay == 'end_month')) table.drop_column('delay', exception=True) lines = cls.search([]) for line in lines: if line.percentage: cls.write([line], { 'divisor': cls.round(Decimal('100.0') / line.percentage, cls.divisor.digits[1]), }) # Migration from 2.4: drop required on sequence table.not_null_action('sequence', action='remove') # Migration from 3.8: rename percentage into ratio if table.column_exist('percentage'): cursor.execute(*sql_table.update( columns=[sql_table.ratio], values=[sql_table.percentage / 100])) table.drop_column('percentage')
def _execute(app, database, user, payload_json): """ Execute the task identified by the given payload in the given database as `user`. """ if database not in Pool.database_list(): # Initialise the database if this is the first time we see the # database being used. with Transaction().start(database, 0, readonly=True): Pool(database).init() with Transaction().start(database, 0): Cache.clean(database) with Transaction().start(database, user) as transaction: Async = Pool().get('async.async') DatabaseOperationalError = backend.get('DatabaseOperationalError') # De-serialize the payload in the transaction context so that # active records are constructed in the same transaction cache and # context. payload = Async.deserialize_payload(payload_json) try: with Transaction().set_context(payload['context']): results = Async.execute_payload(payload) except RetryWithDelay, exc: # A special error that would be raised by Tryton models to # retry the task after a certain delay. Useful when the task # got triggered before the record is ready and similar cases. transaction.connection.rollback() raise app.retry(exc=exc, countdown=exc.delay) except DatabaseOperationalError, exc: # Strict transaction handling may cause this. # Rollback and Retry the whole transaction if within # max retries, or raise exception and quit. transaction.connection.rollback() raise app.retry(exc=exc)
def __register__(cls, module_name): pool = Pool() Sale = pool.get('sale.sale') cursor = Transaction().connection.cursor() TableHandler = backend.get('TableHandler') sql_table = cls.__table__() sale = Sale.__table__() table = TableHandler(cls, module_name) number_exists = table.column_exist('number') # Migration from 3.8: rename reference into number if table.column_exist('reference') and not number_exists: table.column_rename('reference', 'number') number_exists = True super(SaleOpportunity, cls).__register__(module_name) table = TableHandler(cls, module_name) # Migration from 2.8: make party not required and add number as # required table.not_null_action('party', action='remove') if not number_exists: cursor.execute(*sql_table.update(columns=[sql_table.number], values=[sql_table.id], where=sql_table.number == Null)) table.not_null_action('number', action='add') # Migration from 3.4: replace sale by origin if table.column_exist('sale'): cursor.execute(*sql_table.select( sql_table.id, sql_table.sale, where=sql_table.sale != Null)) for id_, sale_id in cursor.fetchall(): cursor.execute( *sale.update(columns=[sale.origin], values=['%s,%s' % (cls.__name__, id_)], where=sale.id == sale_id)) table.drop_column('sale', exception=True)
def __register__(cls, module_name): pool = Pool() AccountEntry = pool.get('analytic.account.entry') TableHandler = backend.get('TableHandler') cursor = Transaction().cursor super(AnalyticMixin, cls).__register__(module_name) handler = TableHandler(cursor, cls, module_name) # Migration from 3.4: analytic accounting changed to reference field if handler.column_exist('analytic_accounts'): entry = AccountEntry.__table__() table = cls.__table__() cursor.execute( *table.select(table.id, table.analytic_accounts, where=table.analytic_accounts != None)) for line_id, selection_id in cursor.fetchall(): cursor.execute( *entry.update(columns=[entry.origin], values=['%s,%s' % (cls.__name__, line_id)], where=entry.selection == selection_id)) handler.drop_column('analytic_accounts')
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() pool = Pool() Category = pool.get('product.category') sql_table = cls.__table__() category = Category.__table__() table = TableHandler(cls, module_name) category_exists = table.column_exist('category') # Migration from 3.8: rename account_category into accounts_category if table.column_exist('account_category'): table.column_rename('account_category', 'accounts_category') super(Template, cls).__register__(module_name) # Migration from 3.8: duplicate category into account_category if category_exists: # Only accounting category until now cursor.execute(*category.update([category.accounting], [True])) cursor.execute(*sql_table.update([sql_table.account_category], [sql_table.category]))
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor sql_table = cls.__table__() super(MenuItem, cls).__register__(module_name) table = TableHandler(cursor, cls, module_name) if table.column_exist('reference'): # pragma: no cover table.not_null_action('unique_name', 'remove') # Delete the newly created record column table.drop_column('record') # Rename the reference column as record table.column_rename('reference', 'record', True) # The value of type depends on existence of record cursor.execute(*sql_table.update( columns=[sql_table.type_], values=['record'], where=(sql_table.record != None) # noqa ))
def _pg_dump(cache_file): cmd = ['pg_dump', '-f', cache_file, '-F', 'c'] options, env = _pg_options() cmd.extend(options) cmd.append(DB_NAME) try: return not subprocess.call(cmd, env=env) except OSError: cache_name, _ = os.path.splitext(os.path.basename(cache_file)) # Ensure any connection is left open database = backend.get('Database')(DB_NAME) database.close() with Transaction().start( None, 0, close=True, autocommit=True, _nocache=True) \ as transaction: database.kill_other_sessions(transaction.connection, DB_NAME) with Transaction().start( None, 0, close=True, autocommit=True, _nocache=True) \ as transaction: transaction.database.create(transaction.connection, cache_name, DB_NAME) open(cache_file, 'a').close() return True
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() pool = Pool() Line = pool.get('account.invoice.payment_term.line') sql_table = cls.__table__() line = Line.__table__() super(PaymentTermLineRelativeDelta, cls).__register__(module_name) line_table = TableHandler(Line, module_name) # Migration from 3.4 fields = ['day', 'month', 'weekday', 'months', 'weeks', 'days'] if any(line_table.column_exist(f) for f in fields): columns = ([line.id.as_('line')] + [Column(line, f) for f in fields]) cursor.execute(*sql_table.insert( columns=[sql_table.line] + [Column(sql_table, f) for f in fields], values=line.select(*columns))) for field in fields: line_table.drop_column(field, exception=True)
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() pool = Pool() ModelData = pool.get('ir.model.data') model_data = ModelData.__table__() # Migration from 3.6: remove double module old_table = 'ir_module_module_config_wizard_item' if TableHandler.table_exist(old_table): TableHandler.table_rename(old_table, cls._table) cursor.execute(*model_data.update( columns=[model_data.model], values=[cls.__name__], where=(model_data.model == 'ir.module.module.config_wizard.item'))) table = TableHandler(cls, module_name) # Migrate from 2.2 remove name table.drop_column('name') super(ModuleConfigWizardItem, cls).__register__(module_name)
def _pg_restore(cache_file): with Transaction().start( None, 0, close=True, autocommit=True, _nocache=True) \ as transaction: transaction.database.create(transaction.connection, DB_NAME) cmd = ['pg_restore', '-d', DB_NAME] options, env = _pg_options() cmd.extend(options) cmd.append(cache_file) try: return not subprocess.call(cmd, env=env) except OSError: cache_name, _ = os.path.splitext(os.path.basename(cache_file)) database = backend.get('Database')(cache_name) with Transaction().start( None, 0, close=True, autocommit=True, _nocache=True) \ as transaction: database.kill_other_sessions(transaction.connection, cache_name) transaction.database.drop(transaction.connection, DB_NAME) transaction.database.create( transaction.connection, DB_NAME, cache_name) return True
def create_table(self): TableHandler = backend.get('TableHandler') model = ModelEmulation() model.__doc__ = self.name model._table = self.name if TableHandler.table_exist(self.name): TableHandler.drop_table('', self.name) table = TableHandler(model) for name, field in (('create_uid', fields.Integer), ('write_uid', fields.Integer), ('create_date', fields.Timestamp), ('write_date', fields.Timestamp)): sql_type = field._sql_type table.add_column(name, sql_type) for field in self.fields: sql_type = FIELD_TYPE_SQL[field.type] table.add_column(field.name, sql_type) return table
def create_db(name=DB_NAME, lang='en'): Database = backend.get('Database') if not db_exist(name): database = Database() database.connect() connection = database.get_connection(autocommit=True) try: database.create(connection, name) finally: database.put_connection(connection, True) database = Database(name) connection = database.get_connection() try: with connection.cursor() as cursor: database.init() ir_configuration = Table('ir_configuration') cursor.execute(*ir_configuration.insert( [ir_configuration.language], [[lang]])) connection.commit() finally: database.put_connection(connection) pool = Pool(name) pool.init(update=['res', 'ir'], lang=[lang]) with Transaction().start(name, 0): User = pool.get('res.user') Lang = pool.get('ir.lang') language, = Lang.search([('code', '=', lang)]) language.translatable = True language.save() users = User.search([('login', '!=', 'root')]) User.write(users, { 'language': language.id, }) Module = pool.get('ir.module') Module.update_list()
def __register__(cls, module_name): pool = Pool() Party = pool.get('party.party') ContactMechanism = pool.get('party.contact_mechanism') TableHandler = backend.get('TableHandler') cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) party = Party.__table__() address = cls.__table__() mechanism = ContactMechanism.__table__() super(Address, cls).__register__(module_name) # Migration from 2.8: move phone and email to contact mechanisms for column in ['email', 'phone']: if table.column_exist(column): join = address.join( party, condition=(party.id == address.party) ) select = join.select( address.create_date, address.create_uid, address.write_date, address.write_uid, As(Literal(column), 'type'), As(Column(address, column), 'value'), address.party, As(Literal(True), 'active'), where=(Column(address, column) != '') ) insert = mechanism.insert( columns=[ mechanism.create_date, mechanism.create_uid, mechanism.write_date, mechanism.write_uid, mechanism.type, mechanism.value, mechanism.party, mechanism.active, ], values=select) cursor.execute(*insert) table.column_rename(column, '%s_deprecated' % column)
def start(self, database_name, user, readonly=False, context=None, close=False, autocommit=False, _nocache=False): ''' Start transaction ''' Database = backend.get('Database') assert self.user is None assert self.database is None assert self.close is None assert self.context is None if not database_name: database = Database().connect() else: database = Database(database_name).connect() Flavor.set(Database.flavor) self.connection = database.get_connection(readonly=readonly, autocommit=autocommit) self.user = user self.database = database self.readonly = readonly self.close = close self.context = context or {} self.create_records = {} self.delete_records = {} self.delete = {} self.timestamp = {} self.counter = 0 self._datamanagers = [] self._nocache = _nocache if not _nocache: from trytond.cache import Cache try: Cache.clean(database.name) except BaseException: self.stop(False) raise return self
def login(dbname, loginname, parameters, cache=True, context=None): DatabaseOperationalError = backend.get('DatabaseOperationalError') for count in range(config.getint('database', 'retry'), -1, -1): with Transaction().start(dbname, 0, context=context) as transaction: pool = _get_pool(dbname) User = pool.get('res.user') try: user_id = User.get_login(loginname, parameters) except DatabaseOperationalError: if count: continue raise except (LoginException, RateLimitException): # Let's store any changes done transaction.commit() raise break session = None if user_id: if not cache: session = user_id else: with Transaction().start(dbname, user_id): Session = pool.get('ir.session') session = user_id, Session.new() # AKE: manage session on redis if config_session_redis(): if config_session_exclusive(): redis.del_sessions(dbname, user_id) redis.set_session(dbname, user_id, session.key, loginname) logger.info("login succeeded for '%s' from '%s' on database '%s'", loginname, _get_remote_addr(context), dbname) else: logger.error("login failed for '%s' from '%s' on database '%s'", loginname, _get_remote_addr(context), dbname) return session
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor table = TableHandler(cursor, cls, module_name) sql_table = cls.__table__() # Migration from 2.2 new field currency created_currency = table.column_exist('currency') super(ProductSupplier, cls).__register__(module_name) # Migration from 2.2 fill currency if not created_currency: Company = Pool().get('company.company') company = Company.__table__() limit = cursor.IN_MAX cursor.execute(*sql_table.select(Count(sql_table.id))) product_supplier_count, = cursor.fetchone() for offset in range(0, product_supplier_count, limit): cursor.execute(*sql_table.join( company, condition=sql_table.company == company.id).select( sql_table.id, company.currency, order_by=sql_table.id, limit=limit, offset=offset)) for product_supplier_id, currency_id in cursor.fetchall(): cursor.execute(*sql_table.update( columns=[sql_table.currency], values=[currency_id], where=sql_table.id == product_supplier_id)) # Migration from 2.4: drop required on sequence table.not_null_action('sequence', action='remove') # Migration from 2.6: drop required on delivery_time table.not_null_action('delivery_time', action='remove')
def __register__(cls, module_name): TimesheetWork = Pool().get('timesheet.work') TableHandler = backend.get('TableHandler') cursor = Transaction().cursor table_project_work = TableHandler(cursor, cls, module_name) table_timesheet_work = TableHandler(cursor, TimesheetWork, module_name) project = cls.__table__() timesheet = TimesheetWork.__table__() migrate_sequence = (not table_project_work.column_exist('sequence') and table_timesheet_work.column_exist('sequence')) super(Work, cls).__register__(module_name) # Migration from 2.0: copy sequence from timesheet to project if migrate_sequence: cursor.execute(*timesheet.join( project, condition=project.work == timesheet.id).select( timesheet.sequence, timesheet.id)) for sequence, id_ in cursor.fetchall(): cursor.execute(*project.update(columns=[project.sequence], values=[sequence], where=project.work == id_)) # Migration from 2.4: drop required on sequence table_project_work.not_null_action('sequence', action='remove') # Migration from 3.4: change effort into timedelta effort_duration if table_project_work.column_exist('effort'): cursor.execute(*project.select( project.id, project.effort, where=project.effort != Null)) for id_, effort in cursor.fetchall(): duration = datetime.timedelta(hours=effort) cursor.execute( *project.update([project.effort_duration], [duration], where=project.id == id_)) table_project_work.drop_column('effort')
def __register__(cls, module_name): pool = Pool() PriceList = pool.get('product.price_list') TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() sql_table = cls.__table__() price_list = PriceList.__table__() super(SaleExtra, cls).__register__(module_name) table = TableHandler(cls, module_name) # Migration from 3.6: price_list not required and new company table.not_null_action('price_list', 'remove') query = sql_table.join( price_list, condition=sql_table.price_list == price_list.id).select( sql_table.id, price_list.company, where=sql_table.company == Null) cursor.execute(*query) for extra_id, company_id in cursor.fetchall(): query = sql_table.update([sql_table.company], [company_id], where=sql_table.id == extra_id) cursor.execute(*query)
def __register__(cls, module_name): pool = Pool() ModelData = pool.get('ir.model.data') TableHandler = backend.get('TableHandler') sql_table = cls.__table__() model_data_sql_table = ModelData.__table__() cursor = Transaction().connection.cursor() # Migration from 3.6: remove double module old_table = 'ir_module_module' if TableHandler.table_exist(old_table): TableHandler.table_rename(old_table, cls._table) super(Module, cls).__register__(module_name) # Migration from 4.0: rename installed to activated cursor.execute(*sql_table.update( [sql_table.state], ['activated'], where=sql_table.state == 'installed')) cursor.execute(*sql_table.update( [sql_table.state], ['not activated'], where=sql_table.state == 'uninstalled')) # Migration from 4.6: register buttons on ir module button_fs_ids = [ 'module_activate_button', 'module_activate_cancel_button', 'module_deactivate_button', 'module_deactivate_cancel_button', 'module_upgrade_button', 'module_upgrade_cancel_button', ] cursor.execute(*model_data_sql_table.update( [model_data_sql_table.module], ['ir'], where=((model_data_sql_table.module == 'res') & (model_data_sql_table.fs_id.in_(button_fs_ids)))))
def _listen(cls, dbname): Database = backend.get('Database') database = Database(dbname) if not database.has_channel(): raise NotImplementedError logger.info("listening on channel '%s' of '%s'", cls._channel, dbname) conn = database.get_connection() try: cursor = conn.cursor() cursor.execute('LISTEN "%s"' % cls._channel) conn.commit() while cls._listener.get(dbname) == threading.current_thread(): readable, _, _ = select.select([conn], [], []) if not readable: continue conn.poll() while conn.notifies: notification = conn.notifies.pop() if notification.payload: reset = json.loads(notification.payload) for name in reset: inst = cls._instances[name] inst._clear(dbname) except Exception: logger.error("cache listener on '%s' crashed", dbname, exc_info=True) raise finally: database.put_connection(conn) with cls._listener_lock: if cls._listener.get(dbname) == threading.current_thread(): del cls._listener[dbname]
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor pool = Pool() Move = pool.get('stock.move') sql_table = cls.__table__() move_table = Move.__table__() super(InventoryLine, cls).__register__(module_name) table = TableHandler(cursor, cls, module_name) # Migration from 2.8: Remove constraint inventory_product_uniq table.drop_constraint('inventory_product_uniq') # Migration from 3.0: use Move origin if table.column_exist('move'): cursor.execute(*sql_table.select( sql_table.id, sql_table.move, where=sql_table.move != Null)) for line_id, move_id in cursor.fetchall(): cursor.execute(*move_table.update( columns=[move_table.origin], values=['%s,%s' % (cls.__name__, line_id)], where=move_table.id == move_id)) table.drop_column('move')
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') table_h = TableHandler(cls, module_name) table = cls.__table__() cursor = Transaction().connection.cursor() super(Work, cls).__register__(module_name) # Migration from 4.0: remove required on name table_h.not_null_action('name', 'remove') # Migration from 4.0: remove parent, left and right if table_h.column_exist('parent'): id2name = {} id2parent = {} cursor.execute(*table.select(table.id, table.parent, table.name)) for id_, parent, name in cursor: id2name[id_] = name id2parent[id_] = parent for id_, name in id2name.iteritems(): parent = id2parent[id_] while parent: name = '%s\\%s' % (id2name[parent], name) parent = id2parent[parent] cursor.execute( *table.update([table.name], [name], where=table.id == id_)) table_h.drop_column('parent') table_h.drop_column('left') table_h.drop_column('right') # Migration from 4.0: remove timesheet_available if table_h.column_exist('timesheet_available'): cursor.execute(*table.delete( where=table.timesheet_available == False)) table_h.drop_column('timesheet_available')
def test_0010_test_failure_counter(self): context = CONTEXT.copy() with Transaction().start(DB_NAME, USER, context=context) as txn: self.setup_defaults() app = self.get_app() txn.cursor.commit() DatabaseOperationalError = backend.get('DatabaseOperationalError') @transaction_start.connect def incr_error_count(app): """ Subscribe to the transaction_start to increment the counter """ self.error_counter += 1 CONFIG['retry'] = 4 with app.test_client() as c: try: c.get('fail-with-transaction-error') except DatabaseOperationalError: self.assertEqual(self.error_counter, 5)
def __register__(cls, module_name): pool = Pool() Property = pool.get('ir.property') TableHandler = backend.get('TableHandler') cursor = Transaction().connection.cursor() table = cls.__table__() super(Party, cls).__register__(module_name) table_h = TableHandler(cls, module_name) if table_h.column_exist('lang'): cursor.execute( *table.select(table.id, table.lang, order_by=table.lang)) for lang_id, group in groupby(cursor.fetchall(), lambda r: r[1]): ids = [id_ for id_, _ in group] if lang_id is not None: value = '%s,%s' % (cls.lang.model_name, lang_id) else: value = None Property.set('lang', cls.__name__, ids, value) table_h.drop_column('lang') # Migration from 3.8 table_h.not_null_action('name', 'remove')
def __register__(cls, module_name): TableHandler = backend.get('TableHandler') cursor = Transaction().cursor pool = Pool() Group = pool.get('account.payment.group') super(Message, cls).__register__(module_name) # Migration from 3.2 if TableHandler.table_exist(cursor, Group._table): group_table = TableHandler(cursor, Group, module_name) if group_table.column_exist('sepa_message'): group = Group.__table__() table = cls.__table__() cursor.execute(*group.select( group.id, group.sepa_message, group.company)) for group_id, message, company_id in cursor.fetchall(): cursor.execute(*table.insert( [table.message, table.type, table.company, table.origin, table.state], [[message, 'out', company_id, 'account.payment.group,%s' % group_id, 'done']])) group_table.drop_column('sepa_message')
def drop_db(name=DB_NAME): if db_exist(name): Database = backend.get('Database') database = Database(name) database.close() with Transaction().start( None, 0, close=True, autocommit=True, _nocache=True) \ as transaction: # PJA: fix concurrent access when dropping database attempt = 0 max_attempts = 10 while True: attempt += 1 try: database.drop(transaction.connection, name) break except: if attempt > max_attempts: raise else: time.sleep(3) Pool.stop(name) Cache.drop(name)
def restore(database_name, password, data, update=False): Database = backend.get('Database') security.check_super(password) try: database = Database().connect() cursor = database.cursor() cursor.close(close=True) raise Exception("Database already exists!") except Exception: pass Database.restore(database_name, data) logger.info('RESTORE DB: %s', database_name) if update: with Transaction().start(database_name, 0) as transaction: cursor = transaction.cursor cursor.execute(*ir_lang.select(ir_lang.code, where=ir_lang.translatable)) lang = [x[0] for x in cursor.fetchall()] cursor.execute(*ir_module.select(ir_module.name, where=(ir_module.state == 'installed'))) update = [x[0] for x in cursor.fetchall()] Pool(database_name).init(update=update, lang=lang) logger.info('Update/Init succeed!') return True
def _listen(cls, dbname): Database = backend.get('Database') database = Database(dbname) if not database.has_channel(): raise NotImplementedError logger.info("listening on channel ir_update of '%s'", dbname) conn = database.get_connection() try: cursor = conn.cursor() cursor.execute('LISTEN "ir_update"') conn.commit() while cls._listener.get(dbname) == threading.current_thread(): readable, _, _ = select.select([conn], [], []) if not readable: continue conn.poll() while conn.notifies: notification = conn.notifies.pop() if notification.payload: reset = json.loads(notification.payload) for name in reset: me = get_worker_id() if 'init_pool' in name and me != name.split( '|')[-1]: cls.on_init_pool(dbname) except Exception: logger.error("IWC listener on '%s' crashed", dbname, exc_info=True) raise finally: database.put_connection(conn) with cls._listener_lock: if cls._listener.get(dbname) == threading.current_thread(): del cls._listener[dbname]
def threaded_send_email(email, smtp_server): """ A new threaded email sender. This is required because there is no transaction in the new thread that is spawned and sendemail tries to create a new cursor from an existing transaction. So create the new transaction here, refresh the active record objects and call sendmail like the cron would have """ with Transaction().start(DB_NAME, USER, context=CONTEXT): # email active record is from old transaction, so referesh it. email = EmailQueue(email.id) database = backend.get('database') try: # Now send the email email.send(smtp_server) except database.DatabaseOperationalError: # This specific email could not be sent because of a # transaction serialization error searialization_error_q.put(email.id) finally: Cache.drop(DB_NAME)