Переключение журнала регистрации в старый формат
Введение
Новый формат журнала регистрации был реализован в платформе «1С:Предприятие 8» в версии 8.3.5.1068. Начиная с этой версии при создании новой информационной базы журнал регистрации будет храниться в одном файле базы данных SQLite с расширением .lgd, который располагается:
- Для файлового варианта информационной базы — в подкаталоге 1Cv8Log каталога информационной базы.
- Для клиент‑серверного варианта информационной базы – в подкаталоге 1Cv8Log каталога информационной базы в каталоге служебных файлов кластера. Имя каталога можно определить по файлу реестра данных кластера.
Целью переработки журнала регистрации и перевода его в новый формат было увеличение скорости выполнения запросов к нему и повышение надежности хранения данных. Новость об этом была размещена на официальном ресурсе фирмы 1С. Обновление платформы до версии 8.3.5.1068 и выше не приводит к автоматическому переводу журнала регистрации в новый формат у уже созданных информационных баз.
Проблемы при работе с новым форматом журнала регистрации
При работе с новым форматом журнала регистрации иногда возникает ряд проблем, которые могут оказаться критичными для стабильной работы пользователей в системе. Приведем ниже типичные проблемы, а также сообщения об ошибках и записи технологического журнала, которые возникают при работе с новым форматом журнала регистрации. Причины данных ошибок мы расследовали в ходе работ по поддержке наших клиентов.
Итак, одна из проблем возникает после перезапуска кластера серверов или аварийного завершения работы менеджера кластера. При этом возможно разрушение структуры файла журнала регистрации .lgd. При попытке открыть такой журнал регистрации происходит ошибка:
sqlite3_step failed: database disk image is malformed
Также иногда можно заметить проявление следующей ошибки при попытке в конфигураторе открыть файл журнала регистрации нового формата:
sqlite3_exec failed: attempt to write a readonly database
Еще одна ошибка связана с медленной работой или зависанием на записи в журнал регистрации, использующим новый формат. В технологическом журнале, при этом, можно увидеть следующие записи:
0,EXCP,1,process=rmngr,p:processName=RegMngrCntxt,p:processName=ServerJobExecutorContext,Exception=81029657-3fe6-4cd6-80c0-36de78fe6657,Descr=’src\RemoteInterfaceImpl.cpp(963):
81029657-3fe6-4cd6-80c0-36de78fe6657: Передача данных прервана по инициативе принимающей стороны.’
Данная строка ТЖ говорит о том, что процесс rmngr центрального сервера не отвечает, так как занят работой с журналом регистрации. И далее в технологическом журнале можно видеть следующие записи:
0,EXCP,0,process=rmngr,p:processName=RegMngrCntxt,p:processName=ServerJobExecutorContext,Exception=81029657-3fe6-4cd6-80c0-36de78fe6657, Descr=’src\RMngrCalls.cpp(549):
81029657-3fe6-4cd6-80c0-36de78fe6657:server_addr=tcp://[сервер]:[порт] descr=Сервер недоступен (Не отвечает, завершается аварийно или порт занят другим приложением) line=1073 file=src\DataExchangeTcpClientImpl.cpp’
Помимо этого, достаточно часто возникает проблема с высоким потреблением памяти журналом регистрации в новом формате. Данное поведение проявляется, например, если кто‑то из пользователей случайно запустит выборку по ЖР без ограничения по периоду. При этом весь журнал регистрации попадет в память, вытеснит весь кэш и «положит» сервер.
Данные проблемы являются достаточно критичными и при их проявлении рекомендуется перевести журнал регистрации в старый формат.
Перевод журнала регистрации в старый формат
Штатные средства платформы 1С не позволяют перевести журнал регистрации из нового формата в старый. Здесь мы опишем способ, который позволит выполнить данную задачу вручную. Итак, для начала необходимо остановить службу 1С. При этом, необходимо согласовать данное действие с пользователями, так как при этом они не смогут работать с информационными базами, которые находятся в соответствующих кластерах 1С.
После того как служба 1С остановлена, переходим в каталог файлов информационной базы для которой необходимо изменить формат журнала регистрации. Данный каталог выглядит следующим образом:
…\1cv8\[каталог служебных файлов службы 1С, обычно srvinfo]\reg_ + [номер порта менеджера кластера]\[UUID информационной базы]
Уникальный идентификатор информационной базы (UUID) можно получить из файла «1CV8Clst. lst», который располагается в каталоге реестра кластера. Для быстрого получения идентификаторов баз и их имен из файла реестра кластера можно воспользоваться следующим регулярным выражением:
\{(\w{8}\-.*\w{12})\,\»(.*?)\»\,.*[\\r]*\n+.*\»\,\d+\}
Далее в каталоге файлов информационной базы ищем папку «1Cv8Log» и переносим оттуда все файлы в отдельный каталог. Затем в папке «1Cv8Log» создаем пустой файл журнала регистрации в старом формате «1Cv8.lgf».
После того, как все этапы данной процедуры выполнены, запускаем службу 1С. Готово, теперь журнал регистрации переведен в старый формат. Чтобы обратно вернуться к новому формату ЖР воспользуйтесь инструкцией, описанной во введении данной статьи.
Заключение
В статье мы постарались описать возможные проблемы при работе с новым форматом журнала регистрации. Такие проблемы чаще всего возникают на предприятиях с большим числом пользователей 1С. Далее мы описали способ перехода с нового формата на старый. Это может быть полезно, так как на данный момент не существует стандартных средств, предоставляемых платформой 1С, которые бы позволили это сделать.
Надеемся, вы сможете с легкостью выполнить нужную вам задачу и продолжите с удовольствием пользоваться продуктами 1С. Ну а если у вас что‑то не получится, или вы столкнетесь с какими‑то трудностями, обращайтесь к нам, мы обязательно поможем!
Как изменить формат отправляемого документа в 1С- ЭДО?
Размер шрифта
Обычная версия
- Посмотреть
- Посмотреть
21.07.2021
Многие пользователи не догадываются, что сервис 1С-ЭДО поддерживает возможность формирования электронных документах разработанных ФНС. Форматы данных документов описаны приказами:
- ПРИКАЗ от 19 декабря 2018 г. N ММВ-7-15/820@
- ПРИКАЗ от 13 апреля 2016 г. N ММВ-7-15/189@
- ПРИКАЗ от 30 ноября 2015 г. N ММВ-7-10/552@
- ПРИКАЗ от 30 ноября 2015 г. N ММВ-7-10/551@
- ПРИКАЗ от 27 августа 2019 г. N ММВ-7-15/423@
При первоначальной настройке устанавливается формат по умолчанию, если он вам не подходит можно изменить его вручную. Рассмотрим данную операцию на примере конфигурации Бухгалтерия предприятия, ред. 3.0.
Во-первых, необходимо найти нужного контрагента в справочнике Контрагенты и вызвать команду ЭДО – Настройки отправки документов
После этого появится форма «Настройки отправки документов по контрагенту». Чтобы перейти непосредственно к настройкам нужно дважды нажать строку табличной части.
Откроется форма с настройками отправки документа. Для изменения формата отправки нужно перейти к настройке отправки документов конкретного типа. Для этого следует перейти по гиперссылке, расположенной напротив наименования документа учета, и в поле «Формат электронного документа» выбрать требуемый формат из выпадающего списка.
Для сохранения настроек нужно нажать на кнопку «Готово», убедиться, что в настройках отправки документов, напротив документа установлен выбранный формат, после чего нажать «Записать и закрыть».
Отдельно хотелось бы отметить изменение статуса УПД.
Счет-Фактура и документ реализации товаров (услуг) в одном документе – статус 1 |
|
Документ реализации товаров (услуг) в формате УПД, но раздельно со Счетом-Фактурой |
|
Более подробно ознакомиться с данным вопросом можно в электронном справочнике 1С-ЭДО: https://1c-edo.ru/handbook/22/4116/
Возврат к списку
python — __init__.py : TypeError: формат %d: требуется число, а не str
Я новичок в Python. Я пытаюсь создать простой веб-сервер, который извлекает данные из моей базы данных mongodb
.
Это моя архитектура файлов:
Это мой код:
# База данных CONNECTION_URL = os.environ['mongoConnectionURL'] DATABASE_NAME = os.environ['mongoDatabaseName'] NEWS_COLLECTION = os.environ['mongodbNewsCollection'] приложение = FastAPI() # В TODO JS есть следующая функция, о которой я пока не знаю app.add_middleware( CORSMпромежуточное ПО, разрешить_origins=['*'], allow_headers=["Происхождение, X-Requested-With, Content-Type, Accept"], ) @app. get('/') индекс определения(): вернуть 'Смотреть / записи' @app.get('/записи') определение getEntries(): клиент = MongoClient(CONNECTION_URL) databaseMongo = client.get_database(DATABASE_NAME) коллекцияMongo = база данныхMongo.get_collection(NEWS_COLLECTION) результат = список (коллекцияMongo.find()) для входа в результат: возвращаться { 'данные': результат } если __name__ == "__main__": uvicorn.run(приложение, порт=os.environ['ПОРТ'])
Это моя ошибка:
Трассировка (последний последний вызов): Файл "/usr/local/lib/python3.9/logging/__init__.py", строка 1083, в файле emit msg = self.format(запись) Файл "/usr/local/lib/python3.9/logging/__init__.py", строка 927, в формате вернуть fmt.format (запись) Файл "/usr/local/lib/python3.9/logging/__init__.py", строка 663, в формате запись.сообщение = запись.получитьсообщение() Файл "/usr/local/lib/python3.9/logging/__init__.py", строка 367, в getMessage сообщение = сообщение % self. args TypeError: формат %d: требуется число, а не str
Более длинный журнал ошибок:
- python
- fastapi
2
uvicorn.run(приложение, порт=os.environ['ПОРТ'])
Эта линия вызывает проблему. порт
должен быть целым числом, но вы передаете его как строку.
Преобразуйте его в целое число, заключив значение в int()
, например:
uvicorn.run(app, port=int(os.environ['PORT']))
Я думаю, это потому, что порт — это str, а не int — попробуйте изменить последнюю строку на:
uvicorn.run(app, port=int(os.environ['PORT']))
Зарегистрируйтесь или войдите в систему
Зарегистрируйтесь с помощью Google
Зарегистрироваться через Facebook
Зарегистрируйтесь, используя адрес электронной почты и пароль
Опубликовать как гость
Электронная почта
Требуется, но никогда не отображается
Опубликовать как гость
Электронная почта
Требуется, но не отображается
python — форматирование строк: % против .
format против литерала f-строкиЗадавать вопрос
спросил
Изменено 8 месяцев назад
Просмотрено 1,0 м раз
Существуют различные методы форматирования строк:
- Python <2.6:
«Привет %s» % имя
- Python 2.6+:
"Привет {}".format(name)
(используетсястр.формат
) - Python 3.6+:
f"{name}"
(использует f-строки)
Что лучше и для каких ситуаций?
Следующие методы дают одинаковый результат, так в чем же разница?
имя = "Алиса" "Здравствуйте, %s" % имя "Здравствуйте, {0}".format(имя) f"Привет, {имя}" # Использование именованных аргументов: "Привет, %(kwarg)s" % {'kwarg': имя} "Привет {kwarg}". format(kwarg=имя) f"Привет, {имя}"
Когда выполняется форматирование строк и как избежать снижения производительности во время выполнения?
Если вы пытаетесь закрыть повторяющийся вопрос, который просто ищет способ форматирования строки, используйте Как поместить значение переменной в строку?.
- python
- производительность
- форматирование строк
- f-строка
7
Чтобы ответить на ваш первый вопрос… .format
во многих отношениях кажется более сложным. Раздражает вещь о %
также может принимать переменную или кортеж. Вы могли бы подумать, что всегда будет работать следующее:
"Привет %s" % name
однако, если name
окажется (1, 2, 3)
, он выдаст TypeError
. Чтобы гарантировать, что он всегда печатается, вам нужно сделать
"Hello %s" % (name,) # указать один аргумент как кортеж из одного элемента
что просто уродливо. .format
не имеет этих проблем. Также во втором примере, который вы привели, 9Пример 0003 .format выглядит намного чище.
Используйте его только для обратной совместимости с Python 2.5.
Чтобы ответить на ваш второй вопрос, форматирование строки происходит одновременно с любой другой операцией — когда вычисляется выражение форматирования строки. И Python, не будучи ленивым языком, оценивает выражения перед вызовом функций, поэтому выражение log.debug("некоторая отладочная информация: %s" % some_info)
сначала оценит строку, например. "некоторая отладочная информация: roflcopters активны"
, затем эта строка будет передана в log.debug()
.
17
То, что не может сделать оператор по модулю ( % ), afaik:
tu = (12,45,22222,103,6) print '{0} {2} {1} {2} {3} {2} {4} {2}'.format(*tu)
результат
12 22222 45 22222 103 22222 6 22222
Очень полезно.
Еще один момент: format()
, будучи функцией, может использоваться в качестве аргумента в других функциях:
ли = [12,45,78,784,2,69,1254,4785,984] напечатать карту('число равно {}'.format,li) Распечатать из datetime импортировать дату и время, timedelta Once_upon_a_time = дата и время (2010, 7, 1, 12, 0, 0) дельта = дельта времени (дни = 13, часы = 8, минуты = 20) gen =(once_upon_a_time +x*дельта для x в xrange(20)) print '\n'.join(map('{:%Y-%m-%d %H:%M:%S}'.format, gen))
Результат:
['число 12', 'число 45', 'число 78', 'число 784', 'число 2', 'число 69', 'число 1254', 'число 4785', 'число 984'] 2010-07-01 12:00:00 2010-07-14 20:20:00 2010-07-28 04:40:00 2010-08-10 13:00:00 2010-08-23 21:20:00 2010-09-06 05:40:00 2010-09-19 14:00:00 2010-10-02 22:20:00 2010-10-16 06:40:00 2010-10-29 15:00:00 2010-11-11 23:20:00 2010-11-25 07:40:00 2010-12-08 16:00:00 2010-12-22 00:20:00 2011-01-04 08:40:00 2011-01-17 17:00:00 2011-01-31 01:20:00 2011-02-13 09:40:00 2011-02-26 18:00:00 2011-03-12 02:20:00
10
Предполагая, что вы используете модуль Python logging
, вы можете передать аргументы форматирования строки в качестве аргументов методу . debug()
вместо самостоятельного форматирования:
log.debug("некоторая отладочная информация: % с", некоторая_информация)
, который позволяет избежать форматирования, если только регистратор действительно что-то не регистрирует.
12
Начиная с Python 3.6 (2016) вы можете использовать f-строки для замены переменных:
>>> происхождение = "Лондон" >>> пункт назначения = "Париж" >>> f"от {отправителя} до {назначения}" 'из Лондона в Париж'
Обратите внимание на префикс f"
. Если вы попробуете это в Python 3.5 или более ранней версии, вы получите SyntaxError
.
См. https://docs.python.org/3.6/reference/lexical_analysis.html# f-строки
2
PEP 3101 предлагает заменить оператор %
новым расширенным форматированием строк в Python 3, где он будет использоваться по умолчанию.
2
Но, пожалуйста, будьте осторожны, только что я обнаружил одну проблему при попытке заменить все %
на .format
в существующем коде: '{}'.format(unicode_string)
попытается закодировать unicode_string и вероятно, потерпит неудачу.
Просто взгляните на этот интерактивный журнал сеансов Python:
Python 2.7.2 (по умолчанию, 27 августа 2012 г., 19:52:55) [GCC 4.1.2 20080704 (Red Hat 4.1.2-48)] на linux2 ; с='й' ; у=у'й' ; с '\xd0\xb9' ; ты у'\u0439'
s
— это просто строка (называемая «массивом байтов» в Python3), а u
— это строка Unicode (называемая «строкой» в Python3):
; '%SS '\xd0\xb9' ; '%s' % и у'\u0439'
Когда вы передаете объект Unicode в качестве параметра оператору %
, он создаст строку Unicode, даже если исходная строка не была Unicode:
; '{}'. формат(ы) '\xd0\xb9' ; '{}'.format(u) Traceback (последний последний вызов): Файл "", строка 1, в UnicodeEncodeError: кодек 'latin-1' не может кодировать символ u'\u0439' в позиции 0: порядковый номер вне диапазона (256)
, но функция .format
вызовет «UnicodeEncodeError»:
; u'{}'.формат(ы) и'\xd0\xb9' ; u'{}'.format(u) у'\u0439'
, и он будет работать с аргументом Unicode, только если исходная строка была Unicode.
; '{}'.format(u'i') 'я'
или если строка аргумента может быть преобразована в строку (так называемый «массив байтов»)
8
%
дает лучшую производительность, чем формат
из моего теста.
Тестовый код:
Python 2.7.2:
время импорта напечатать 'формат:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'привет')") напечатать '%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'привет')")
Результат:
> формат: 0,4703249 > %: 0,357107877731
Python 3. 5.2
время импорта print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'привет')")) print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'привет')"))
Результат
> формат: 0,5864730989560485 > %: 0,013593495357781649
Это выглядит в Python2, разница небольшая, тогда как в Python3 %
намного быстрее, чем формат
.
Спасибо @Chris Cogdon за образец кода.
Изменить 1:
Повторно протестировано в Python 3.7.2 в июле 2019 года.
Результат:
> формат: 0.86600608 > %: 0,630180146
Большой разницы нет. Я предполагаю, что Python постепенно улучшается.
Редактировать 2:
После того, как кто-то упомянул f-строку Python 3 в комментарии, я провел тест для следующего кода в Python 3.7.2:
import timeit print('format:', timeit.timeit("'{}{}{}'.format(1, 1.23, 'привет')")) print('%:', timeit.timeit("'%s%s%s' % (1, 1.23, 'привет')")) print('f-string:', timeit. timeit("f'{1}{1.23}{\"привет\"}'"))
Результат:
формат: 0.8331376779999999 %: 0,6314778750000001 f-строка: 0,766649943
Кажется, f-строка все еще медленнее, чем %
, но лучше, чем формат
.
10
Еще одно преимущество .format
(которого я не вижу в ответах): он может принимать свойства объекта.
В [12]: класс А (объект): ....: def __init__(я, х, у): ....: сам.х = х ....: сам.у = у ....: В [13]: а = А(2,3) В [14]: 'x равно {0.x}, y равно {0.y}'.format(a) Out[14]: 'x равно 2, y равно 3'
Или, как аргумент ключевого слова:
В [15]: 'x равно {a.x}, y равно {a.y}'.format(a=a) Out[15]: 'x равно 2, y равно 3'
Это невозможно с %
, насколько я могу судить.
5
Как я обнаружил сегодня, старый способ форматирования строк через %
не поддерживает Decimal
, модуль Python для десятичной арифметики с фиксированной и плавающей запятой, из коробки.
Пример (с использованием Python 3.3.5):
#!/usr/bin/env python3 из десятичного импорта * получитьконтекст().prec = 50 d = Десятичный ('3.12375239e-24') # никакого магического числа, я скорее произвел его, ударившись головой о клавиатуру печать('%.50f' % д) печать('{0:.50f}'.формат(г))
Вывод:
0.00000000000000000000000031237523
00009907464850 0.0000000000000000000000031237523
00000000000000
Конечно, могут быть обходные пути, но вы все равно можете сразу же рассмотреть возможность использования метода format()
.
2
Если ваш python >= 3.6, литерал в формате F-строки — ваш новый друг.
Это проще, чище и производительнее.
В [1]: params=['Привет', 'адам', 42] В [2]: %timeit "%s %s, ответ на все %d."%(params[0],params[1],params[2]) 448 нс ± 1,48 нс на петлю (среднее значение ± стандартное отклонение для 7 запусков, 1 000 000 циклов в каждом) В [3]: %timeit "{} {}, ответ на все: {}. ".format(*params) 449 нс ± 1,42 нс на петлю (среднее значение ± стандартное отклонение для 7 циклов, 1000000 циклов в каждом) В [4]: %timeit f"{params[0]} {params[1]}, ответ на все: {params[2]}." 12,7 нс ± 0,0129нс на цикл (среднее значение ± стандартное отклонение для 7 запусков, 100000000 циклов каждый)
1
В качестве примечания: вам не нужно снижать производительность, чтобы использовать форматирование в новом стиле с ведением журнала. Вы можете передать любой объект в logging.debug
, logging.info
и т. д., который реализует магический метод __str__
. Когда модуль регистрации решает, что он должен выдать ваш объект сообщения (что бы это ни было), он вызывает str(message_object)
, прежде чем сделать это. Таким образом, вы можете сделать что-то вроде этого:
журнал импорта класс NewStyleLogMessage (объект): def __init__(я, сообщение, *args, **kwargs): self. message = сообщение self.args = аргументы self.kwargs = кварги защита __str__(я): args = (i() if callable(i) else i для i в self.args) kwargs = dict((k, v() if callable(v) else v) for k, v в self.kwargs.items()) вернуть self.message.format(*args, **kwargs) N = НьюСтилелогмессаже # Ни одно из этих сообщений не форматируется (или вычисляется), пока не будет # нужный # Выдает в лог "лениво отформатированную запись: 123 foo" logging.debug(N('Запись журнала с ленивым форматированием: {0} {keyword}', 123, keyword='foo')) защита дорогая_функция(): # Сделать что-то, что занимает много времени... вернуть "фу" # Выдает в лог "Дорогая запись в логе: foo" logging.debug(N('Дорогая запись в журнале: {ключевое слово}', ключевое слово=expensive_func))
Все это описано в документации Python 3 (https://docs.python.org/3/howto/logging-cookbook.html#formatting-styles). Однако он будет работать и с Python 2.6 (https://docs.python.org/2.6/library/logging. html#using-arbitrary-objects-as-messages).
Одним из преимуществ использования этого метода, помимо того факта, что он не зависит от стиля форматирования, является то, что он допускает ленивые значения, например. выше функция , дорогая_функция
. Это более элегантная альтернатива советам, данным в документации по Python здесь: https://docs.python.org/2.6/library/logging.html#optimization.
2
Одна из ситуаций, когда %
может помочь, — это форматирование выражений регулярных выражений. Например,
'{type_names} [a-z]{2}'.format(type_names='треугольник|квадрат')
вызывает IndexError
. В этой ситуации вы можете использовать:
'%(type_names)s [a-z]{2}' % {'type_names': 'треугольник|квадрат'}
Это позволяет избежать записи регулярного выражения как '{type_names} [a-z]{{2}}'
. Это может быть полезно, когда у вас есть два регулярных выражения, одно из которых используется без форматирования, а конкатенация обоих форматируется.
2
Я бы добавил, что начиная с версии 3.6 мы можем использовать fstrings, как показано ниже:
foo = "john" бар = "кузнец" print(f"Меня зовут {foo} {bar}")
Которые дают
Меня зовут Джон Смит
Все преобразовано в строки
mylist = ["foo", "bar"] печать (f"мой список = {мой список}")
Результат:
мой список = [‘фу’, ‘бар’]
вы можете передать функцию, как и в методе других форматов
print(f'Привет, вот дата: {time.strftime("%d/%m/%Y")}')
Подача например
Здравствуйте, вот дата: 16.04.2018
0
Сравнение Python 3.6.7:
#!/usr/bin/env python импортировать время определение time_it (fn): """ Измерение времени выполнения функции """ обертка def (*args, **kwargs): t0 = timeit. default_timer() fn(*args, **kwargs) t1 = timeit.default_timer() печать ("{0:.10f} секунд". формат (t1 - t0)) возвратная упаковка @time_it определение новый_новый_формат(ы): print("new_new_format:", f"{s[0]} {s[1]} {s[2]} {s[3]} {s[4]}") @time_it определение новый_формат(ы): print("new_format:", "{0} {1} {2} {3} {4}".format(*s)) @time_it def old_format(s): print("old_format:", "%s %s %s %s %s" % s) деф основной(): образцы = (("uno", "dos", "tres", "cuatro", "cinco"), (1,2,3,4,5), (1.1, 2.1, 3.1, 4.1, 5.1), ( "уно", 2, 3.14, "куатро", 5.5)) для s в выборках: новый_новый_формат(ы) новый_формат(ы) старый_формат(ы) Распечатать("-----") если __name__ == '__main__': основной()
Вывод:
new_new_format: uno dos tres cuatro cinco 0,0000170280 секунд new_format: uno dos tres cuatro cinco 0,0000046750 секунд old_format: uno dos tres cuatro cinco 0,0000034820 секунд ----- новый_новый_формат: 1 2 3 4 5 0,0000043980 секунд новый_формат: 1 2 3 4 5 0,0000062590 секунд старый_формат: 1 2 3 4 5 0,0000041730 секунд ----- новый_новый_формат: 1.