
    bi                        d dl Z d dlZd dlmZmZ d dlmZ d dlmZ d dlmZ d dl	m
Z
 d dlZd dlZd dlZd dlZd dlmZ d dlmZmZmZ d d	lmZmZ d d
lmZ d dlmZ d dlmZ d dlmZ d dlm Z  d dl!m"Z"m#Z# d dl$m%Z% d dl&m'Z' ddl(m)Z)m*Z*m+Z+ ddl,m-Z-m.Z.m/Z/m0Z0 ddl1m2Z2m3Z3m4Z4m5Z5 ddl6m7Z7 ddl8m9Z9m:Z: d dlmZm;Z;m<Z<  G d de2          Z= G d d          Z>dS )    N)defaultdict
namedtuple)copy)List)OrderedDict)	timedelta)IntegrityError)
ForeignKeyfuncinspect)jsong)Config)command)UNIQUE_VIOLATION)errors)close_all_sessions)
CmfRelBaseCmfType)fields)models   )CmfOrmErrorCmfOrmUniqueErrorCmfOrmIntegrityError)BaseModelMetaDEFAULT_DATASOURCE	BaseModelCmfGM2MModel   )BaseDataDriver
BaseMapperMapperinc_select_count)imutable_deep_copy)cache_obj_lock_release_allemit_delayed_events)r   DictAnyc                   l    e Zd ZdZi Z ej                    Zej        j	        
                    ee          Z e            ZdZd Z fdZed             Zed             Zed             ZedJd	            ZdJd
Zd Zd Zd Zd Zd Zed             Zd Zd Zd Zd Z d Z!e"d             Z#e"d             Z$ e%dd          Z&dKdZ'e"dLde(e&         fd            Z)dJdZ*e"d              Z+ej,        dddfd!Z-e"d"             Z.e"d#             Z/d$ Z0e"dMd%            Z1dJd&e&fd'Z2dddd(d)Z3ddddddddddd*
d+Z4ddd,d-Z5ddddddd.d/Z6dNd0Z7d1 Z8d2 Z9dd3d4Z:d5 Z;dNd6Z<ddd7d8e=fd9Z>d:d;d<Z?dd=d>Z@dd=d?ZA fd@ZBdA ZCdB ZDdC ZEdD ZFdOdEZGe fdF            ZHdG ZIdH ZJdI ZK xZLS )PSQLAlchemyDataDriveru  
    dataproviders['default'] = {
        'type': 'sqlalchemy',
        'sqlachemy.url': 'postgresql://user:password@host/db',
        'sqlachemy.echo': True,  # Достаточно для отладки запросов в develop mode
    }

    # Для отладки в продакшене логгеры:
    sqlalchemy.engine - controls SQL echoing. set to
        logging.INFO for SQL query output, logging.
        DEBUG for query + result set output.
        These settings are equivalent to echo=True and echo="debug" on create_engine.echo, respectively.
    sqlalchemy.pool - controls connection pool logging.
         set to logging.INFO to log connection invalidation and recycle events;
         set to logging.DEBUG to additionally log all pool checkins and checkouts.
         These settings are equivalent to pool_echo=True and pool_echo="debug" on create_engine.echo_pool, respectively.
    sqlalchemy.dialects - controls custom logging for SQL dialects, to the extend that logging
         is used within specific dialects, which is generally minimal.
    sqlalchemy.orm - controls logging of various ORM functions to the extent that logging
         is used within the ORM, which is generally minimal.
         Set to logging.INFO to log some top-level information on mapper configurations.

    Example:
        logging.basicConfig()
        logging.getLogger('sqlalchemy.engine').setLevel(logging.INFO)
    )class_registrymetadataNc                 L    t           j                            | j                  S )N)bind)
sqlalchemyormsessionmakerengineselfs    "./cmf/data_providers/sqlalchemy.py_session_factoryz%SQLAlchemyDataDriver._session_factoryF   s    ~***<<<    c                 >    t                      j        |i | t          j        | j        fi d |                                D             | _        t          j                            | 	                                          | _
        |                                  d S )Nc                 n    i | ]2\  }}|                     d           |                    d dd          |3S )zsqlalchemy. r    )
startswithreplace).0kvs      r6   
<dictcomp>z1SQLAlchemyDataDriver.__init__.<locals>.<dictcomp>j   sP       Aq<<..		-Q//  r8   )super__init__r0   engine_from_configconfigitemsr3   r1   scoped_sessionr7   Session	init_meta)r5   argskwargs	__class__s      r6   rC   zSQLAlchemyDataDriver.__init__e   s    $)&))) 3K
 
 "LLNN  
 
 "~44T5J5J5L5LMMr8   c                    g }|j                                         D ][\  }}t          |t                    r|j        s|j        s+d |g}g }|j        rt          |j                  }|j        r|r|j        rd|vrt          d| d|j	         d          |D ]}|dk    r*|
                    t          j        |d|j        i           2|dk    r<|
                    t          j        d|j         d| d| |d	|d
i                     t|
                    t          j        d|j         d| d| |||j                             2|
                    t          j        |d|j        i           ]t          |d          r?|j        r8|
                    t          j        d|j         dg|j        dR ddi           |S )Ndefaultu   В поле .uU    указана уникальность, но не указан индекс defaultuniquegin_trgmix__gingin_trgm_ops)postgresql_usingpostgresql_ops)rV   rP   orderno_partition_by_orderno_partition_by_clusterordernoF)r   rF   
issubclassr   indexrP   index_usinglistr   
class_nameappendr0   Index	tablenamehasattrrX   )cls	cmf_modelindexescmf_field_name	cmf_fieldrJ   r]   idx_types           r6   __get_indexesz"SQLAlchemyDataDriver.__get_indexess   s   )2)9)?)?)A)A #	M #	M%NI)Z00 O y'7 .)DK$ :"9#899 ; # n	(D(D%  'mY  'm  'mAU  'm  'm  'm  n  n  n +  H  9,,z'7'WiFV'W'WXXXX!Z//z'7S)"5SSSSSS*-2"0.,	( ( (          z'7S)"5SSSSSS*-5#,#3	( ( (     NN:+TK):JKKLLLL 9455 	):X 	NN:+T)"5TTT&; &   $)	     r8   c                 r    | j                             |          }|r| j                             |           |S N)cached_queriesgetmove_to_end)rd   keyrets      r6   	get_queryzSQLAlchemyDataDriver.get_query   s>     ""3'' 	0**3///
r8   c                 f   || j         |<   | j        sPt          j        d          t          j        d          z  dz  dz  }|dz  }|dz  }|dk     rd}|dk    rd}|| _        t	          | j                   | j        k    r2| j                             d          \  }}t          d	|            d S d S )
NSC_PAGE_SIZESC_PHYS_PAGESi   i         F)lastzDEV: set_query evicted key )rm   cached_queries_limitossysconflenpopitemprint)rd   queryrp   sys_memsize_mbchunk_countqueries_limitevicted_keyrS   s           r6   	set_queryzSQLAlchemyDataDriver.set_query   s    "'3
 ' 	5Z77"*_:U:UUX\\_ccN(C/K'",Mr!! "s"" #'4C$s!""S%=== /77U7CCNK===>>>>> >=r8   c                 n   |j         }|j        rdS t          |t          j                  rt          j                    }nOt          |t          j                  rt
          j        }n't          |t          j	                  r!t          j
        |j        |j                  }nt          |t          j                  re|t          j        |j                  g}|j        r'|                    t%          |j                             t          j        ||j        |j        dS t          |t          j                  rt          j                    }n>t          |t          j                  rt          j        |j                  }n	t          |t          j                  rt          j        |j                  }nt          |t          j                  rdS t          |t          j                  rdS t          |t          j                  rdS t          |t          j                  rdS t          |t          j                  rdS t          |t          j                   rt          j!        d          }nt          |t          j"                  rt          j#                    }nt          |t          j$                  rt          j                    }nt          |t          j%                  rdS t          |t          j&                  rdS t          |t          j'                  rt
          j(        }n\t          |t          j)                  rt
          j*        }n5t          |t          j+                  r	ddl,m-} |}nt]          d|           t          j        |||j/        |j        |j                  S )	u0   Создадим SA поле для моделиN)primary_keynullableT)timezoner   )TSVECTORu"   Не найден тип поля )rN   r   r   )0r_   virtualr[   r   	CmfBigIntr0   BIGINTCmfIntInteger
CmfNumericNumeric	precisionscaleCmfTUUIDString
max_lengthforeign_keyr`   r
   Columnr   r   CmfTextTEXTCmfStrCmfBytesLargeBinaryCmfRelationCmfGenericRelationCmfGenericM2MCmfDateRangeCmfM2MCmfDateTime	TIMESTAMPCmfDateDATECmfJson
CmfBackrefCmfGenericBackrefCmfBoolBooleanCmfTimeTimeCmfTsVectorsqlalchemy.dialects.postgresqlr   	ExceptionrN   )rd   
_cmf_modelrh   _db_field_namecolumn_namesa_typerJ   r   s           r6   _make_sa_columnz$SQLAlchemyDataDriver._make_sa_column   sr     * 	4i!122 ;	N '))GG	6=11 9	N (GG	6#455 7	N ()<ioNNGG	6?33 5	N!293G!H!HID $ ?Jy'<==>>>$9#89CU    	6>22 ,	N o''GG	6=11 *	N '	(<==GG	6?33 (	N ,Y-ABBGG	6#566 &	N4 	6#<== 	N4	6#788 	N4	6#677 	N4	6=11 	N4	6#566 	N *D999GG	6>22 	N o''GG	6>22 	N o''GG	6#455 	N4	6#;<< 	N4	6>22 	N (GG	6>22 	N oGG
 	6#566 	N??????GG LLLMMM %'!-
 
 
 	
r8   c                 X    t          | j                                      ||          }|S )N)schema)r   r3   get_columns)r5   
table_namer   columnss       r6   inspect_table_columnsz*SQLAlchemyDataDriver.inspect_table_columns  s)    $+&&22:f2MMr8   c                     |                      |          }| j        j                            | j        |j                  S rl   )dp_modelr3   dialect	has_table	__table__)r5   re   sa_models      r6   r   zSQLAlchemyDataDriver.has_table  s3    ==++{",,T[(:LMMMr8   c                    |                      d |          j        }t          |t          j                  r| d}t          d           |                                 }d| d| d| }|j        s|j        d| | d|j         d}t          d	           |	                    |           t          d
           |
                                 t          d           d S )NTZzadd_custom_column open sessionzalter table z add column IF NOT EXISTS  uH   Значение по умолчанию не может быть None: z	 default z	 NOT NULLzadd_custom_column run executezadd_custom_column run commitzadd_custom_column done)r   typer[   r   r   r~   rH   r   rN   executecommit)r5   r   r   cmf_field_typesa_column_typessqls          r6   add_custom_columnz&SQLAlchemyDataDriver.add_custom_column  s   --dNCCHnf&899 	3 .222N.///LLNNaZaa;aaQ_aa& 	E%-qaoqqqDD>#9DDDC-...			#,---	


&'''''r8   c                 p   dddd}t          j        t           j        ddd          |d<   t          j        t           j        ddd          |d	<   t          j        t           j        d
d          |d<   t          j        t           j        dd          |d<   t	          |t
          f|          }ddl}t          j        |	                    dd                     | 
                    |          rt          d| d           dS ddl}t          j        |	                    dd                     | 
                    |          rt          d| d           dS t          j                            |j        j                  }|                                 }	 t          d           |                    |           t          d           |                                 t          d           dS # t(          $ r9}|j                                         t          d| d|            Y d}~dS d}~ww xY w)u5   
        Создаем М2М таблицу
        Tcustom.r;   abstract
__module____qualname__u   ID Объекта)captionr   r\   left_idu   ID Элементаright_id   Имя объекта)r   r   left_name_cacheu   Имя элементаright_name_cacher   N皙?g      ?u$   add_custom_m2m_model Таблица uT    уже создана в БД. Вероятно, на другом инстансеz!add_custom_m2m_model create tablezadd_custom_m2m_model run commitzadd_custom_m2m_model doneuB   add_custom_m2m_model Ошбика создания таблицы : )r   Fieldr   	CmfStr256r   r   randomtimesleepuniformr   r~   r0   r   CreateTabler   r   rH   r   r   r   transactionrollback)r5   
model_namerK   re   r   smtpr   es           r6   add_custom_m2m_modelz)SQLAlchemyDataDriver.add_custom_m2m_model.  sv    #)RPP"LBU`dlpqqqy#\&/CXcgostttz$*L1AKbmq$r$r$r !%+\&2BLept%u%u%u!"l_f==	 	
6>>#s++,,,>>)$$ 	  Y  Y  Y  Y  Z  Z  ZF 	
6>>#s++,,,>>)$$ 	  Y  Y  Y  Y  Z  Z  ZF ,,Y-?-IJJLLNN	d5666IIdOOO3444HHJJJ-..... 	d 	d 	dM""$$$bW[bb_`bbccccccccc	ds   AG2 2
H5<.H00H5c           	      \   dddd}t          j        t           j        dddddd          |d	<   t          j        t           j        d
d          |d<   t          j        t           j        ddddd          |d<   t          j        t           j        ddddd          |d<   t          j        t           j        dddd          |d<   t          j        t           j        ddddd          |d<   t          j        t           j        ddddd           |d<   t          |t          f|          }|S )NTr   r;   r   u)   Идентификатор объектаu3   Автоматически генерируетсяF)r   commentr   r   readonlyvisibleidr   )r   r\   nameu   Сортировкаr   )r   r\   r   r   rN   rZ   u   Кодu3   Код в реальном мире из жизни)r   rP   r   r   r   codeu:   Код родителя в каскадном выборе)r   r   r   r\   choice_parent_idu   Скрыть
cmf_hiddenu!   Конфигурация поляcust_field_conf_id)	r   r   r   r   r   CmfStr64r   r   r   )r5   r   rK   re   s       r6   gen_custom_choice_modelz,SQLAlchemyDataDriver.gen_custom_choice_modelR  sx   ")RPP|O?I
 
 
t  +
 
 
v
 #LM*
 
 
y  OI
 
 
v &,\OP&
 &
 &
!"  &|N" 
  
  
| (.|O7(
 (
 (
#$ i\6::	r8   c                    |                      |          }t          j                            |j        j                  }|                                 }	 |                    |           |                                 dS # t          $ r9}|j
                                         t          d| d|            Y d}~dS d}~ww xY w)ur   
        Создаем пользовательский справочник выбора таблицу
        u-   Ошбика создания таблицы r   N)r   r0   r   r   r   r   rH   r   r   r   r   r   r~   )r5   r   re   r   r   r   s         r6   add_custom_choice_modelz,SQLAlchemyDataDriver.add_custom_choice_model  s     00<<	 ,,Y-?-IJJLLNN	OIIdOOOHHJJJJJ 	O 	O 	OM""$$$M$MM!MMNNNNNNNNN	Os   )A? ?
C	.B==Cc                 (   |j         }| j                            |          }|s|j        }g }g }ddi}|j                                        D ]6\  }}	|}
|                     ||	|
          }|!|                    |           7|                    | 	                    |                     |                    |           |t          |          d}|                    d |D                        t          || j        f|          }|| j        |<   |S )u]   
        Вернём SA модель для CMF модели.
        TODO: db_name
        extend_existingTN)__tablename____table_args__c                     i | ]
}|j         |S  r   r>   cs     r6   rA   z5SQLAlchemyDataDriver.dp_model_cls.<locals>.<dictcomp>  s    #B#B#B!AFA#B#B#Br8   )__name__models_registryrn   rb   r   rF   r   r`   extend"_SQLAlchemyDataDriver__get_indexestupleupdater   sa_base_model)rd   re   r   r   rb   
sa_columnsr   __table_kwargs__rg   rh   sa_field_name	sa_columnsa_model_kwargss                r6   dp_model_clsz!SQLAlchemyDataDriver.dp_model_cls  sO    '
&**:66 	7 "+IJN 148-6-=-C-C-E-E - -)	 .//	9mTT	$!!),,,,!!#"3"3I">">???!!    "+"'"7"7 O ""#B#Bz#B#B#BCCCJ):(<oNNH.6C
+r8   c                 ,    |                      |          S rl   )r
  )r5   re   s     r6   r   zSQLAlchemyDataDriver.dp_model  s      +++r8   c                 6    t          t          |j                  S )uG   
        Вернём CMF модель для SA модели.
        )getattrr   r   )r5   r   s     r6   re   zSQLAlchemyDataDriver.cmf_model  s     vx0111r8   c                 6    t          |t          j                  S rl   )
isinstancer+   r  )r5   dp_instances     r6   is_instancez SQLAlchemyDataDriver.is_instance  s    +';'IJJJr8   c                     i }|D ] }|j         j        ||j         j        j        <   !t          j                            |d|          S )N
table_type)r   r   fullnamer0   r1   polymorphic_union)r5   
cmf_modelsaliastablesmodels        r6   _union_modelsz"SQLAlchemyDataDriver._union_models  sN     	Q 	QE8=8PF5>+455
 ~//eLLLr8   c	                     	 dfd	}	i }
|D ] }|j         j        |
|j         j        j        <   ! |	|
d                              |          S )Np_unionTc                   
 t           j                                        }i i | D ]}| |         t          t           j        j                  s	                                 | |<   i }j        D ]A}r
|j        vr|	                    |j                   |||j        <   |j
        |j        <   B|<   fd
g }|                                 D ]w\  }	||                    t           j                            
fd|D             t           j                            t           j        j                            |	                                        |          gz   g                              t%          j         d          j        j        k                                                       |                    t           j                            
fd|D             g                              t%          j         d          j        j        k                                                       yt          j        j        |                     |          S )NTc                    	 |         |          S # t           $ r rWt          j                            t          j                                        |                                        |           cY S t          j                            t          j                                        |                                        |           cY S w xY wrl   )KeyErrorr0   r   castnulllabeltype_coerce)r   table
cast_nullscolnamemapstypess     r6   colzPSQLAlchemyDataDriver._union_models2.<locals>.hack_polymorphic_union.<locals>.col  s    j&u-d33 j j j! j)~22:>3F3F3H3H%PT+VV\\]abbbbb)~99*.:M:M:O:OQVW[Q\]]ccdhiiiii	js    A!C4ACCc                 (    g | ]} |          S r   r   r>   r   r(  r$  s     r6   
<listcomp>zWSQLAlchemyDataDriver._union_models2.<locals>.hack_polymorphic_union.<locals>.<listcomp>  %    CCC$SSu--CCCr8   from_obj_idc                 (    g | ]} |          S r   r   r*  s     r6   r+  zWSQLAlchemyDataDriver._union_models2.<locals>.hack_polymorphic_union.<locals>.<listcomp>#  r,  r8   )r0   util
OrderedSetr  r   Selectr  r   rp   addr   rF   r`   selectliteral_column_quote_ddl_exprr"  wherer  r   correlate_except	union_all)	table_maptypecolname	aliasnamer%  colnamesrp   mr   resulttype_r(  r&  r$  r'  left_field_name
left_tablesub_ffls      `      @@@@r6   hack_polymorphic_unionzCSQLAlchemyDataDriver._union_models2.<locals>.hack_polymorphic_union  s    "1133HKE   '  '!#( eZ^%:;; + +!KKMME%*IcN * *A !15#7#7 LL''' AaeH#$6E!%LL%&E""j j j j j j j F ) 1 1  u*MM"--CCCCC(CCC * = =$.N$7$G$G$N$N!" !""'%"4"4 ',W .    %
6M6M6M N NRWRYR\ \]]--e44    MM"--CCCCC(CCCug .  %
6M6M6M N NRWRYR\ \]]--e44	    >+V4::9EEEr8   r  )r  T)r   r   r  lateral)r5   rC  right_tabler  rB  right_modelmodels_is_unionrD  rE  	join_subqr?  s    `  `   `   r6   _union_models2z#SQLAlchemyDataDriver._union_models2  s    HLJ	F J	F J	F J	F J	F J	F J	F J	FZ 	 	L 	LA78z7KIaj*344%%i>>FFuMMMr8   c                     d}| d         |v r| d         | d         | d         fS | d         |v r| d         | d         | d         fS t          d| |          )N)><==>=<==IN!=><<>NOT INLIKENOT LIKEILIKE	NOT ILIKEz
SIMILAR TOzNOT SIMILAR TOEXISTS
NOT EXISTS	MEMBER_OF@@HISTORYNOT HISTORYr   r    r   zInvalid filter operation)r   )paramsop_lists     r6   _parse_paramsz"SQLAlchemyDataDriver._parse_params/  sn    + !9!9fQi22AY'!!!9fQi228&'JJJr8   c                    |dk    rd }| dk    r||k    S | dk    r||k    S | dk    r||k     S | dk    r||k    S | dv r||k    S | dv r||k    S | dk    r|                     |          S | d	k    r|                     |          S | d
k    r|                     |          S | dk    r|                     |           S | dk    r|                    |          S | dk    r|                    |           S | dk    r|                    |          S | dk    r|                    |           S  |                    |           |          S )NNULLrN  rQ  rO  rR  )rP  rS  )rU  rV  rW  rT  r_  r`  rX  rY  rZ  r[  r\  )in_likeilikeop)operfieldvals      r6   _expressionz SQLAlchemyDataDriver._expression=  s}   &==C3;;3;T\\C<S[[3;T\\C<[  C<'''C<T\\99S>>![  99S>>!T\\99S>>!XIIcNN?"V^^::c??"ZJJsOO##W__;;s###[  KK$$$$!588D>>#&&&r8   JoinDatazJleft_table, right_table, alias, left_field_name, right_model, right_modelsTc           
         |r|j         }|j        }n|j                            |          }|s|                     ||           t          |t          j        t          j        f          rt          |t          j                  r t          d|j          d|j          d          |j          d}|r| d| n|}|
                                }	|	s'|r#t          d| d|j          d|j          d          d S |	d	         }
t          |	          d
k    r,t          j                            |
j        j        |          }n6||                     |d |||
|	d|          }n|                     |	|          }|                     |||||
|	          }|S )NuX   Недопустимый тип поля для вложенной фильтрации rO   up   . Вложенная фильтрация возможно только для CmfRelation и CmfGenericRelation_sub__uj   Не возможно построить запрос для вложенной фильтрации по u   , т.к. у поля u#    не указаны related_modelsr   r    r   T)rJ  rD  )r_   instance_classr   rn   _raise_invalid_fieldr[   r   r   CmfSubclassedGenericRelationr   related_modelsr|   r0   r1   aliasedr   r   rL  r  rp  )r5   r  rC  
field_name
from_aliasis_models_required	field_clsrD  
alias_partrI  rH  rG  	join_datas                r6   _calc_join_dataz$SQLAlchemyDataDriver._calc_join_datab  s1    	H"-J,EE((44I =))*e<<<i&*<f>W)XYY H!)V-PQQH!Goto G G  CL  CW G G GH H H ",222
6@P
22j222j
**,, 	! y!x  BL x x+0+;x x>G>Rx x xy y y 4ajw<<1$.001E1OV`0aaKK#--j$
JXcelw{  FM-  N  NKK,,WjAAKMM*k:zS^`ghh	r8   Fjoinsc           	      &   |rt                      n"d | j                                        D             }|D ]Z}|j        |v r|                     |j        t          |j        j        |j	         d          |j        j        j
        k              } [| S )uP  
        TODO cmf_deleted
        Все данные для необходимых присоединений в joins, добавим недостающие присоединения в запрос.
        froms могут быть от филдов, при этом без джойна, чтобы принудительно создать join нужен force = True.
        Или более продвинутый способ определения наличия нужного джойна.
        Сейчас при построении основного запроса, джойны принудительно добавляются.
        А при расчёте фильтров, когда нет алиасов от полей, джойн делается только если нет нужного алиаса.
        c                 d    h | ]-}t          |t          j        j        j                  &|j        .S r   )r  r0   r   
selectableAliasr   )r>   r  s     r6   	<setcomp>z3SQLAlchemyDataDriver._make_joins.<locals>.<setcomp>  sI     /C /C /C%!:!@AA/CJ/C /C /Cr8   r/  )set	statementlocate_all_fromsr  	outerjoinrG  r  rC  r   rB  r   )r   r  forceavailable_joinsr~  s        r6   _make_joinsz SQLAlchemyDataDriver._make_joins  s     $) C#%%% /C /C99;;/C /C /C
  	r 	rI/11OO%	,.93L0Q0Q0QRRV_VkVmVppr rEE r8   c                     d }g }|d }|j         j        }n|j        }|                    d          D ]D}|                     ||||          }|                    |           |j        }|j        }|j        }E|S )NrO   )	r   r   r   splitr  r`   r  rH  rG  )r5   	join_pathr  rC  rz  r  ry  r~  s           r6   _calc_joins_by_pathz(SQLAlchemyDataDriver._calc_joins_by_path  s    
J1JJ#J#//#.. 	/ 	/J,,UJ
JWWILL###"J)E".JJr8   c                     t          |j                                      dd          }t          |  d|j         d|           )N,z,
u+    не существует у модели u   , но есть: 
)strr   r=   r   r_   )ry  r  fields_s      r6   ru  z)SQLAlchemyDataDriver._raise_invalid_field  si    el##++C77Z  C  CTYTd  C  C  zA  C  C  D  D  	Dr8   c	                 >&  ; |s|d fS t          |d         t                    rEg }	|D ]9}
|                     |
||||||          \  }}|$|	                    |           :| ||	 fS |d         dk    r$|                     |dd          ||||||          S |d         dk    r/|                     |dd          |||t          j        |||          S |d         dk    rNt          |          dk    s
|d         d	vrt          d
          |                     ||d         |          }|d fS | 	                    |          \  }}}|
                    d          }|j                            |d                   }d}t          |          dk    rjt          |t          j        t          j        t          j        f          r9|d         }d                    |dd                    ||g}d}||j        j        }nt          |          dk    rz|                    d          \  }}}|                     |||          }|                     ||          }|d         }|j        }|j                            |          }|j        }d}n||j        j        }|dk    r |dk    r|j                            d          }|st          d| d|j                   ||                     ||           ;fd; ;|          }t          |t          j                  r|dv r<t          |t                    s't          |t6                    st          d|||          |d	v r|t          d|||          |dv rddlm} |                     |d||          }|t          d| d           |j        r|j         r|j!        r|"                                }|                     |          }|j        }|j#        r|j$        }|j%        }n'|j&        r|j%        }|j$        }nt          d!||          |                     tN          j(                  }|j        }g }|j         D ]^} | 
                    d          \  }!}"|                    t	          j)        |j*        j+        |"k    |j*        j,        |!k                         _t	          j        | }|j-        .                    |          }#|#/                    |t	          j)        ||j*        j0        k    |                    }#|d	v r0|#1                    ||k              2                                }#||# fS |#1                    ||k    t	          j        | 3                    d"||          | 3                    d"|j*        j4        |                              2                                }#n'|j         r|                     tN          j(                  }$|d	v r\|j-        .                    |$          1                    |$j0        |k    |$j+        |j        k              2                                }#||# fS |j5        st|j-        .                    |$          1                    |$j0        |k    |$j+        |j        k    | 3                    d"|$j4        |                    2                                }#n%t          j6        7                    t          j8        9                    |$j0        g|$g#          :                    |$j0                  ;                    | 3                    d"|$j4        |                    ;                    |$j+        |j        k                        }#|/                    |#t          |#j*                  d         |k              }||d"k    rt          |#j*                  d         d k    nt          |#j*                  d         d k    fS |"                                }$|                     |$          }%|j#        r|%j$        }&|%j%        }'n'|j&        r|%j%        }&|%j$        }'nt          d!||          |d	v rH|j-        .                    |%          1                    |&|k              2                                }#||# fS |j<        sZ|j-        .                    |%          1                    |&|k    | 3                    d"|'|                    2                                }#nt          j6        7                    t          j8        9                    |&g|%g#          :                    |&          ;                    | 3                    d"|'|                              }#|/                    |#t          |#j*                  d         |k              }||d"k    rt          |#j*                  d         d k    nt          |#j*                  d         d k    fS ||d"k    r|#n|# fS |d$v r|                     |d||          }(|(t          d| d%          | =                    | d d d |&          })|)j        }*|)j        }+|j-        .                    |+j*        j>                  },ddlm} |j        r|j         r|j!        r|"                                }|                     |          }|j        }|j#        r|j$        }|j%        }n'|j&        r|j%        }|j$        }nt          d!||          |                     tN          j(                  }-|-j        }.|,/                    |.|.j*        j4        |+j*        j>        k              },g }|j         D ]^} | 
                    d          \  }!}"|                    t	          j)        |.j*        j+        |"k    |.j*        j,        |!k                         _t	          j        | }|,                    |t	          j        ||+j*        j>        k    t	          j)        ||.j*        j0        k    |                              },|,1                    ||(k              },n!|j         r}|                     tN          j(                  }-|-j        }.|,                    |.|-j4        |+j*        j>        k              },|,1                    |-j0        |(k    |-j+        |j        k              },n|j&        rd'}/d(}0nd(}/d'}0|"                                }$|                     |$          }-|-j        }.t          |-|/          }1t          |-|0          }2|,                    |.|2|+j*        j>        k              },|,1                    |1|(k              },t          |+j*        d)          r|sg d*}3ng }3t          |+j*        d+          r|s|3g d,g}3|r|3|g}3|                     |3|*|*j        |,|+||          \  },}3|,1                    |3          },|,2                                },|A                    d-          r|, },||,fS t          d.|||          t          |t          j        t          j        f          rV|dv r|A                    d-          rd/nd}dd"|g}|d$vrt          d0|||          |                     |d||          }(|(t          d| d1          | =                    | d d d |&          }4|4j        }5|4j        }6|jB         d2}7t          |6j*        |7          }8|j-        .                    |8          },|7d3|(g}3t          |6j*        d)          r|3g d*g}3|r|3|g}3|                     |3|5|5j        |,|6||          \  },}3|,1                    |3          },|,2                                },|A                    d-          r|, },||,fS t          |t          jC                  rg| d2}|d4k    r[| =                    | d d d |&          })|)j        }*|)j        }+|j-        .                    |+j*        j>                  },|                     tN          j(                  }-|-j        }.|,                    |.|-j4        |+j*        j>        k              },|,1                    t	          j        | 3                    d"|-j0        |          | 3                    d"|-jD        |                    |-j+        d5k              },|                     ||||          }|t	          j        | 3                    d"||          | 3                    d"||,                    fS |d6v rKt          |t          j                  rt          d7          tN          jF        }*|*j        j        }+|                     |j        d||          }(|(t          d|+ d%          |j-        .                    |+j*        j>                  },d8}0|                     |*          }9t          |9|0          }2|,1                    |2|(k              },|d9d3|j        gg}3|                     |3|*|*j        |,|+:          \  },}3|,1                    |3          },|,2                                },|A                    d-          r|, },||,fS |dk    rbtN          jG        H                    |j        ||ddd;g<          }:|:sd=g}:|                     |d||          }|| 3                    d"||:          fS |                     ||||          }|t          d| d>| d?          || 3                    |||          fS )@Nr   )field_tableinclude_deletedinclude_dummyANDr    OR)cmdr  r  r  order_by   )rS  rP  ut   Операция order_by в фильтре должна быть в формате: ["order_by", "=", [поля..]]r   r  rO   Fr]  )rC  TANYr`  r   u	   Поле u    не найдено у c                 `   ddl m}m} t          | t                    r!| j        du r ||j        d           | j        } t          | t          t          f          rfd| D             } nCt          | t                    r| j        j        } n!t          | t                    rd| v r| d         } | S )Nr   print_debugrE   .u<   collect_filter_exp: Значение не загруженоc                 &    g | ]} |          S r   r   )r>   sub_rnormalize_rights     r6   r+  zTSQLAlchemyDataDriver.collect_filter_exp.<locals>.normalize_right.<locals>.<listcomp>  s#    EEEU//%00EEEr8   r   )cmf.includer  rE   r  r   _valueDEBUGvaluer^   r  r   r   dict)right_r  rE   r  s      r6   r  z@SQLAlchemyDataDriver.collect_filter_exp.<locals>.normalize_right  s    77777777&'** &=C''K.mnnn
 &4-00 	&EEEEfEEE FI.. &FD)) &dfnnMr8   )rT  rX  u   Правое значение для IN, NOT IN для m2m должно быть list, т.е. в квадратных скобках, например "field", "IN", "[obj.id]"u   Недопустимая операция над m2m полем (сравнение = только на None), допустимые IN, NOT IN, = None)rT  rX  rS  rP  rE   
with_aliasu   В таблице u3    нет поля id для фильтрации m2muD   Надо указать для поля либо left либо rightrT  r-  )r]  r^  uG    нет поля id для фильтрации в подзапросе)r|  r   r   cmf_deletedr  rP  Fis_dummyr  rP  FzNOT uh   Недопустимая операция над m2m полем, допустимые IN, NOT IN, = Noner^  ul   Недопустимая операция над backref полем, допустимые EXISTS, NOT EXISTSu7    нет поля id для фильтрации backrefr/  rP  r_  
rg_members)ra  rb  uA   History для м2м полей не поддерживаетсяobj_idry  )r  '  )r   ry  search_queryonly_idssliceNOTFOUNDu    нет поля u    для фильтрации)Ir  r^   collect_filter_expr`   r0   or_r|   r   order_queryre  r  r   rn   r[   
CmfM2MBaser   r   joinr   r   
rpartitionr  r  rH  rG  r_   ru  r  r  rE   _query_columnRELATION_CACHE_EDGE_OPTIMIZEnested_fieldsnested_fields_is_edge_parentm2m_model_clsrightr   r   leftr   RelationCacheand_r   parent_fieldparent_modelsessionr   r  	parent_idfilterexistsro  child_idORM_RELCACHE_EXISTS_VIA_JOINr1   rx  r   r5  distinctr8  ORM_M2M_EXISTS_VIA_JOINr  r   r  rc   r<   backrefCmfRelationBaseparent_coder   CmfOrmColumnHistoryCmfFullSearchfulltext_search)<r5   	in_filterr  r   r   r  r  r  r  
filter_resr@   exprl  r  r  
left_partsr|  r  r  rS   r  r~  rE   field_columnm2m_link_modeldp_m2m_link_modelm2m_link_tabledp_m2m_link_field_selfdp_m2m_link_field_theirrelcache_modelrelcache_table	nf_filternfnf_modelnf_fieldm2m_subquery	m2m_modeldp_m2m_modeldp_m2m_field_selfdp_m2m_field_theirself_columnsub_data	sub_model	sub_table	sub_querym2m_sa_model	m2m_tablemy_id_field_namesub_id_field_namemy_sa_fieldsub_sa_fieldsub_filter_expbackref_databackref_modelbackref_tablebackref_column_namebackref_columnsub_sa_model	found_idsr  s<                                                              @r6   r  z'SQLAlchemyDataDriver.collect_filter_exp  s     	$;	!d++ 	J ' '!44Qx\g  zICP 5 R R
s;!!#&&&&##z***q\U""**9QRR=%5^i  |K9F + H H Hq\T!!**!""uh:>Wb  uD+ + - - - q\Z''9~~""il+&E&E!  #Y  Z  Z  Z$$UIaL$FFE$; !..y99dE ZZ__
L$$Z]33	
z??Qy6+<f>OQWQi*jkk  a=DXXjn--tU;ED"#n6__q  !%!5!5Iq$,,Y+,VVE$$UE22Eb	I)E((..I#/KJJ"#n6 5==TT\\((..I 	\Z$ZZHXZZ[[[%%dE222	 	 	 	 	0  &&i!233 i	^'''E41H1H'JW\^cLdLd'! G  IM  OT  V_` ` ` {""5=! m  os  uz  |EF F F 222......#11+tUWa1bb'%&{;&{&{&{|||6 w9;R wW`W} w &/%<%<%>%>N(,n(E(E%%6%@N  D1B1K.2C2K//" D1B1J.2C2L//)*prw  zC  D  D  D &*]]63G%H%HN%3%=N !#I'5  -/XXc]]*(!((*,9XE*,9XE* *     !+	 :I#(=#6#67H#I#IL $0#9#9.:D/<SWeWgWq<q<E;< ;<$; $;L {** (4':':2lB( ( &(( %  %|m33'3':':2lB&N $ 0 07NPU V V $ 0 0~7G7PRW X X ( ( !&(( % , ? !%f.B C CI{**',}':':9'E'E'L'L%/<?%2i6JJ(L (LLRFHH %  %|m33%B +0=+>+>y+I+I+P+P ) 3| C ) 6):N N $ 0 0y7I5 Q Q,S ,S TZSYS[S[ )L
 ,6>+A+A*.BWBW!*!4 5 CX C C&hy':;;EE$BRBRSWYbYkmrBsBs<t<tuzuz$-$:i>R$RvT vT,U ,UL
 %*OOL$|~BVBVWXBY]iBi$j$jE#(TUY\\$|~*>*>q*AT*I*I_cdpdr_s_stu_vz~_~#~~ !* 7 7 9 9I#'==#;#;L  D,8,A)-9-A**" D,8,@)-9-B**)*prw  zC  D  D  D{**',}':':<'H'H'O'O-=(? (??Evxx %$|m33%= +0=+>+>|+L+L+S+S 1\ A $ 0 07I5 Q Q,S ,SSYSYS[S[ )L ,6>+A+A*.BWBW!2 3|n CX C C&h'899%%@P@PQUWikp@q@q:r:r,t ,tL %*OOL$|~BVBVWXBY]iBi$j$jE#(TUY\\$|~*>*>q*AT*I*I_cdpdr_s_stu_vz~_~#~~ddllllMM///"00dEV`0aa&%  'P;  'P  'P  'P  Q  Q  Q  //dD$R[/\\$0	$0	!M//	??	......6 EM9;R EMW`W} EM &/%<%<%>%>N(,n(E(E%%6%@N  D1B1K.2C2K//" D1B1J.2C2L//)*prw  zC  D  D  D $(==1E#F#FL , 6I ) 3 3Iy{?SW`WbWe?e f fI !#I'5  -/XXc]]*(!((%K4@%K4@* *     !+	 :I )~/9~3Jikn3\3=?4Ky{Od4d4=45 4501 01! !I !* 0 01G;1V W WII, M $(==1E#F#FL , 6I )y,:OS\S^Sa:a b bI ) 0 0$.+=$1Y5II!K !KII !~ 6+4(,6))+5(,5) ) 7 7 9 9I#'==#;#;L , 6I"),8H"I"IK#*<9J#K#KL )y,)+.:X Y YI ) 0 01K L LI9;66 ( (%A%A%ANN%'N9;
33 QM Q&46O6O6O%PN =&4e%<N,0,C,C"Iy/A9Zc  vE"/ -D -1 -1)	> &,,^<<	%,,..	??6** +!*
Ii'' "~  AE  GL  NWX X X	F$5v7O#PQQ 5	^''''+v'>'>L||HtU+333! C%, , , ,,[$R\,]]K"!"{{"{"{"{|||  //dD$R[/\\L(4M(4M%.%6";";";$]_6IJJN++N;;I14EN}66 P"02N2N2N!O 9"0%!8(,(?(?}/Ey^k  ~M+ )@ )- )-%I~ "((88I!((**Iv&& '&J	)##	6#9:: 	^<<<D{""//dD$R[/\\$0	$0	!M//	??	#}}V-ABB(2	%NN9l6Ky{~6]^^	%,,N4#3#3D,:PRW#X#X#'#3#3D,:RTY#Z#Z\ \ -=? ?	  $11+tUWa1bbjnT-=-=dLRW-X-X-1-=-=dLR[-\-\^ ^ ^ ^---)V%677 e cddd2I!*4I,,X-?uYc,ddK"!  #Jy  #J  #J  #J  K  K  K ++IKN;;I (==33L"<1BCCL!(()DEEI#lD):N%OPN(,(?(?	9+=y% )@ )' )'%I~ "((88I!((**Iv&& '&J	)##4<<,<<HXHLJOFJDEu:	 = O OI
  )'L	--k4S]-^^L$**4yIIII ))+tUz)ZZs;ssQUssstttd&&t\5AAAAr8   c                     |  dS )N_m2m_directr   ry  s    r6   _m2m_depth_alias_namez*SQLAlchemyDataDriver._m2m_depth_alias_nameq  s    ))))r8   c                     |  dS )N_m2m_idr   r  s    r6   _m2m_alias_namez$SQLAlchemyDataDriver._m2m_alias_nameu  s    %%%%r8   c                 :   |                     dg           }t          |t                    rt          j        |          }|rt          |d         t
                    s|g}|                                D ]&\  }}||j        v r|                    |d|g           '|S )u   
        Преобразуем обычные kwargs в продвинутый фильтр для однообразной логики фильтрования
        :param model:
        :param kwargs:
        :return:
        r  r   rP  )	rn   r  r  r   loadsr^   rF   r   r`   )r5   r  rK   smart_filterr?   r@   s         r6   _get_filterz SQLAlchemyDataDriver._get_filtery  s     zz(B//lC(( 	4:l33L 	
<?D A A 	L LLNN 	2 	2DAqEL  ##QaL111r8   c                 P   |rR|j                                         D ]8}t          |t          j        j        j                  r| j        |j        k    r|} 9d|v r{|                    d          \  }}|dv rHt          | j
        |d          } t          t          |          |                              |          }n-t          | j
        |d          }nt          | j
        |d          }|:|r6|                    t          |                              dd                    n|S dS )u   Для полей "основной" таблицы не нужен префикс таблицы, для этого нужно указать with_alias=Falsers  )sumavgcountminmaxNrO   )r  r  r  r0   r   r  r  r   r  r  r   r   r"  r  r=   )r$  r   r   r  from_	func_namecolumn_name_shortcolumns           r6   r  z"SQLAlchemyDataDriver._query_column  s/     	"99;; " "eZ^%>%DEE "%*X]XbJbJb!E;+6+<+<T+B+B(I(AAA *;TBB1y11&99??LL +t<<UWk488FCMY6<<F 3 3C > >???SYY r8   parent_joinc           	         |r|j         n|j        j        }|                                D ]\  }|                     |t          |                    }||                    |           B|r|r	|j        pg n|g}	fd|	D             }
|
sd|
d         j        }|r|j	        nd}| 
                    |||d|          }|s|                    |           |                     ||||j        |           dS )u2   Соберём поля и таблицы по fflr  Nc                     g | ]`}|j                                       xt          t           j        t           j        f          Dt          t           j                  ^aS r   )r   rn   r[   r   r   rv  )r>   related_modelr|  ry  s     r6   r+  z?SQLAlchemyDataDriver._select_joined_columns.<locals>.<listcomp>  s     X X X%%2%9%=%=j%I%II	X #9v/A6C\.]^^	X
 'y&2UVVXX X Xr8   r   F)r{  rD  )r  )rG  r   r   rF   r  boolr`   right_modelsrt  r  r  _select_joined_columnsrH  )r5   fflr  r   r  r  r$  rD  r  rw  
fields_cls
left_modelrz  r~  r|  ry  s                 @@r6   r  z+SQLAlchemyDataDriver._select_joined_columns  su   +6T''EN<T#&99;; 	s 	sJ''zd;FWFW'XXF!v&&&& sEP!]+":"@bW\V]X X X X X)7X X X
 " &qM	&5
2=G[..4
 00z:RWah 1 j j	  Y'''++GUGYEZhq+rrr3	s 	sr8   )r  group_byr  c                   |                      |          }|                                 }	ddlm}
 |
                    d|j         |          }t          |                               |          }|r*|                                }|	                    |	          }nt          j
                    }g }g }|                     ||||            |	j        | }|                     ||d          }t          j
                    |z
  dk    rJ|                                	                    d           }t          |                               ||           t          |          dk    r7|j        }t#          t          |                    D ]}||         |||         <   |                     ||          }|r3|                     ||||||          \  }}|                    |          }|r~g }|D ]o}||j        j        v r&|                    |j        j        |                    6| d	|j        j        v r(|                    |j        j        | d	                    p |j        | }|S )
Nr   	CMF_CACHEzquery: full_fields_loadT)r  g{Gz?r  r  r/  )r   rH   r  r$  hashr   r   rr   _clonewith_sessionr   r  r   r  r   r|   r   ranger  r  r  r   r   r`   r!  )r5   r  r&  r  r!  r  rJ   rK   r   r   r$  rp   r   start_calc_timer  r   clone_qpkeyir  
filter_expr   s                         r6   _create_queryz"SQLAlchemyDataDriver._create_query  s   ==''LLNN))))))nn7u~77JZn[[T

$$S)) 	3LLNNE&&q))EE"ikkOEG''(8%%PPPAGW%E$$UE$>>E
 	O+u44  ,,..55d;;T

$$Wc222 t99q==$D3t99%% * *"&q'tAw''v66 	- $ 7 7eXW\n}FS !8 !U !UE:LL,,E 	-G' N N("4"666NN8#5#7#DEEEE#(((H,>,@@@NN8#5#7;8K8K8K#LMMM"ENG,Er8   )
r  r&  r  
for_updatemapperr  load_m2mr!  aggregate_selectr  c       
   	         t          |t                     }t          j        |          }|                     |          }|                     |          } | j        |f||||	|
d|                                }|                     ||||
|          }|r
 |j        | }|
rB|	                                }t          j        d          }|
                    |||          }|S |r|                                }|	                                }|
                    |||          }|r2|r|                     |||||           |r|                                 |S )   Грубо селектим всю таблицу, фильтры:
          - в kwargs: поле -> значение
        )r&  r  r  r!  r5  )r  r5  r  simpler&  r  r'  )r  r"   
get_mappermap_args
map_kwargsr1  with_labelsr  r  alllist_to_cmfwith_for_update	_load_m2mpost_mapping_hook)r5   r  r  r&  r  r2  r3  r  r4  r!  r5  r  rJ   rK   mapper_is_my_argsqsql_resres_objss                      r6   r^   zSQLAlchemyDataDriver.list  s    &fj999&v..d##((D
$4oer  ~F  Yi
 
 ms
 

+-- 	
 QHX`eff 	 A 	eeggG*844F))'DT\a)bbHO (%%''eeggG))*:% * I IH / ENN8-=vWf  wDN  E  E  E /,,...Or8   )r&  r!  c                   |                      |          }|                     |          } | j        |fd|i|                                }|r|                     |          fd|D             }  |j        j        |j        j                             g |t          j
                              j        |                     d          }	t          |j                            |	                    }
g }|
D ]D}i }t!          |          D ]\  }}||         ||<   |d         |d<   |                    |           E|S  |j        j        |j        j                             t          j
                    g                              d          }	|j                            |	                                          }|S )r7  r&  c                 4    g | ]}j         j        |         S r   )r   r   )r>   r   r   s     r6   r+  z.SQLAlchemyDataDriver.count.<locals>.<listcomp>%  s$    UUU[x)+K8UUUr8   Nr  r  )r;  r<  r1  r=  r   r  select_fromfromswith_only_columnsr   r  r!  r  r^   r  r   	enumerater`   scalar)r5   r  r&  r!  rJ   rK   rD  rE  r   count_qres_listresrowrow_resr/  r   r  r   s                    @r6   r  zSQLAlchemyDataDriver.count  s    d##((D
 
$4
8>
 

+-- 	
  	8}}U++HUUUUHUUUG-ak-q{/@A""#;W#;djll#;<<7$ $  AI--g6677HC $ $&/&9&9 2 2NA{+.q6GK((#&r7 

7####J-ak-q{/@ASSUYU_UaUaTbccllmqrrGI%%g..5577Er8   )r  r&  r2  r3  r  r  c                $   t          |t                     }
t          j        |          }|                     |          }|                     |	          }	 | j        |g|R |||d|	}|                                }|                     ||ddg|          }|r|                                }|	                                }|rK|
                    |||          }|                     |g||||           |
r|                                 |S dS )u   
        Выбрать один объект по фильтру:
          - в args - первичный ключ(опционально)
          - в kwargs - другие поля: поле -> значение)r&  r  r  r   r    )r  r  r9  )r3  r  r  N)r  r"   r:  r;  r<  r1  r=  r  r@  firstobject_to_cmfrA  rB  )r5   r  r  r&  r2  r3  r  r  rJ   rK   rC  rE  sa_instanceres_objs                 r6   rn   zSQLAlchemyDataDriver.get8  sZ   
 &fj999&v..}}T""((Du Ft F F>N`o-:F F>DF FMMOOQAeDD 	$!!##Awwyy 	**;IYaf*ggGNNG9&6vWf  wDN  E  E  E +((***N	 	r8   c                 ~  => |r|sdS t          |t                    ==fd>d }t          |          }t          t                    }t          t                    }	t          t                    }
|D ]F}| >|                                       |           |	|j                                     |           G|	D ]}t          t          |          }|D ]}||         st          ||d          }|r~t          |t          j
                  rdt          |t          j                  r	||          [t          |t          j        t          j        f          r|
|                             |           |                                D ]\  }}g }|D ]}t          t          |j                  }|j	                            |          }|rgt          |t          j                  rL=rt          ||          }|j        dur"|j        |                    |j                   d|_        |j        du rd|_        |                                }t          ||          }|j        }|du rt'          d||          nyt          ||d          }|dur|r|                    |           t)          ||d           |                                }t          ||d          }|du rt'          d||          |r<|                    d          d         }||         |                             |           |                                D ]\  }}t          t          |d          }|st-                       dd	t          |          g}|                     |||         ||
          }|D ]J} >|          }||         D ]4}=rt          ||          }||_        ||_        #t)          |||           5K|r |                     |||         |||           |
                                D ]\  }}|D ]}|j        }|	|         }t          ||          }t          |t          j                  r5|j        r-t3                      }|j         d} | d	>fd|D             g}!t5          t3          ||         fi | i i          }"|                                D ]_}#|!}$d|#j	        v r|s|!g dg}$d|#j	        v r|s|$g dg}$|                     |#|"|$||          }%|                     |%|#          ||#j        <   `|s,ddlm }&m!}'  |&|'j"        d|j         d|j         d           2tG          |          dk    rOt-                       tI          tK          |&                                                    '                                }(not-                       | (                    tR          j*        +                    d |                                D             d                    '                                }(t          t                    })|(D ]-}*t          |*|           }+|)|+                             |*           .g },|D ]}|)                     >|                    }-=rt          ||          }|-sg |_        |j        du rg |_        M|,                    |-||                   |_        |j        du rt[          |j                  |_        |,.                    |j                   |-st)          ||g            |,                    |-||                   }t)          |||           |,.                    |           |,r |                     |,||         |||           rt          |t          j                  r|j/        rd}.d}/nd}.d}/|0                                }0| 1                    |0          }1t          |1|.          }2t          |1|/          }3| (                    |2|3          2                    |23                    >fd|D                                 }4t          t                    }5t          t                    }6t-                       |4D ]Y\  }7}8|8r|7s
|6|8                             |7           |5|8                    d          d                                      |8           Z|5                                D ]6\  }}9t          t          |          }t-                       dd	|9g}|sti          |d          rg d|g}|sti          |d          rg d|g}|                     |||         ||d          },|,r |                     |,||         |||           |,D ]}|6 >|                   D ]}7||7         D ]t}:=r3|:|         };|;j        du rg |;_        |;j                            |           7t          |:|d          }|du rg }t)          |:||           |                    |           u8|D ]w}=rO||         }<|<j        du rg |<_        |<j        du rt[          |<j                  |<_        |<5                                 St          ||d          du rt)          ||g            xdS ) u   
        Прогрузка М2М и М2О полей
        :param objs: список обьектов
        :param full_fields_load: поля обьектов
        :return:
        Nc                 .    r| j         j        S | j         S rl   )r   r  )obj_is_heavys    r6   r  z.SQLAlchemyDataDriver._load_m2m.<locals>.obj_id^  s     &w~%7Nr8   c                  &    d } t          |           S )Nc                  *    t          t                    S rl   )r   r^   r   r8   r6   id_to_list_factoryzWSQLAlchemyDataDriver._load_m2m.<locals>.model_to_id_factory.<locals>.id_to_list_factoryj  s    "4(((r8   r   )r_  s    r6   model_to_id_factoryz;SQLAlchemyDataDriver._load_m2m.<locals>.model_to_id_factoryi  s     ) ) )1222r8   .u#   Не загружено id поле:r   r   rT  )r&  r3  r  r'  r/  c                 &    g | ]} |          S r   r   r>   or  s     r6   r+  z2SQLAlchemyDataDriver._load_m2m.<locals>.<listcomp>  s!    :W:W:W66!99:W:W:Wr8   r  r  r  r  )r&  r  r  r  r  r  zORM: skip load field rO   z die no related modelsr    c                 $    i | ]\  }}||j         S r   )r  )r>   r?   r?  s      r6   rA   z2SQLAlchemyDataDriver._load_m2m.<locals>.<dictcomp>  s      M M MDAqAK M M Mr8   r  r   r   c                 &    g | ]} |          S r   r   rd  s     r6   r+  z2SQLAlchemyDataDriver._load_m2m.<locals>.<listcomp><  s!    0M0M0Mq0M0M0Mr8   F)r&  r  r3  r4  )6r  r#   r   r^   r`   r_   r  r   r[   r   r   r  r  CmfBackrefBaserF   rn   r  _oldid_fieldnamer   setattr	partitionr$   rA  r  r  r%   rw  r1  r  rb   r  r  rE   r  r|   nextitervaluesr>  r   r0   r1   r  r?  r   r   r  r  r   r  rh  rc   apply_changes)?r5   objsr&  r3  r  r  ra  to_load_mappingmy_objs_by_idmy_objs_by_model_namemodels_by_rel_fieldsobjr   r  ry  r|  model_to_idalready_loaded_obj_listrm  id_field_nameid_fieldid_field_valuefield_valuerel_model_nameid_to_obj_list_filter	load_objsload_obj	loaded_idmodels_listobj_listm2mquerybackref_field_namefilter_q	field_ffl	rel_modelmodel_query_filterrE  r  rE   rP  res_dictrn  m2m_idsub_objsref_obj_listr  r  r  r   r  r  	m2m_queryid_by_modelsmy_id_by_sub_idmy_idsub_idsub_id_listmy_objmy_field	obj_fieldr\  r  s?                                                                @@r6   rA  zSQLAlchemyDataDriver._load_m2mR  s1      	t 	Fff--	 	 	 	 		3 	3 	3 &&9:: $D)) +D 1 1*400 	> 	>C&&++&--c222!#.188====/ 	G 	GJFJ//E. 
G 
G
'
3  #E:t<<	 GIv7H!I!I G!)V-CDD G'
333#I0A6CX/YZZ G,Z8??FFF
G (7'<'<'>'> H	< H	<#J ')#  #P #P77!L,,Z88	  PIv7M!N!N  P k 'Z 8 8 <s22$|7 7 > >u| L L L$ (, :,,)-EJ(1(>(>(@(@#*3#>#>)1)S00"-.SU]_d"e"ee 1 '.c:s&C&C&c11* L 7 > >{ K K K$  Z666(1(>(>(@(@)0mS)I)I)S00"-.SUbdi"j"jj% P)7)A)A#)F)Fq)I#N3NCJJ3OOO /:.?.?.A.A ? ?*
N
D99  """tN';';< II,<Z,H!' & 3 3	 !* ? ?H &x 0 0I-i8 
? 
?# ?$+C$<$<E+3EL *2EJJ#CX>>>>
?? ' <68H8TV\n}-:  < < <
 (<'A'A'C'C ]	= ]	=#J$ \= \="-
0< $E:66	 i)>?? S=IDU S=  $vvH,5,=)B)B)B& 2D:W:W:W:Wh:W:W:WXH 248H8T3q3qYkmoXp3q3q r rI%.%=%=%?%? ] ]	-5*(I,<<<_<2:<X<X<X1Y.%)999-92DF_F_F_1`. ..y9]o  BQ=J / L L 9=8H8HR[8H8\8\!455# dCCCCCCCC#"LsE4DssyG[sssu u u !X!++(***#'X__->->(?(?#@#@#D#D#F#F(*** $(::&N<< M MHNN<L<L M M M|] ]$^ $^^a^a^c^c !  +400H' 5 5!(.@!A!A (//4444!H' 9 9'/||FF3KK'@'@# 9$+C$<$<E#/ )/1#(:#4#413EJ (+1+=+=lL\]gLh+i+iEL$zS00-1%,-?-?
 %OOEL9999#/ ) 'Z < < < (*0*<*<\K[\fKg*h*hK#C[AAA$OOK8888   Dx1A*1Mvgv5B ' D D D	6+<== G= !~ 6+4(,6))+5(,5) ) 7 7 9 9I#}}Y77H")(4D"E"EK#*85F#G#GL $

; E E0M0M0M0MH0M0M0M N NOO #.t#4#4L&1$&7&7O$&&&)2 N Nv% %U %$'/66u===$V%5%5c%:%:1%=>EEfMMMM3?3E3E3G3G @ @/
K '
 ; ;(***#'{";. N75-3P3P N'C'C'CW&MG, K
1K1K K'@'@'@'&JG#'99!4DZ4P#*6E $- $K $K $ H NN85Ej5QSYkz9F + H H H#+ @ @C)8)E @ @.;E.B !@ !@F'/ 
%@39*3E+3?c+A+A>@HO(0(>(>s(C(C(C(C6=fjRU6V6V+6#+=+=:<K,3FJ,T,T,T(3(:(:3(?(?(?(?!@@@   ( 
= 
=# 	=(+JI(/36635	 0(~4415i6F1G1G	%335555&sJ<<CC 'Z < < <y\=]	= ]	=r8   c                     g }|D ]L}t          |t          j                  r|                    |j                   7|                    |           M|S rl   )r  r   r   r`   r  )r5   rJ   new_argsargs       r6   r;  zSQLAlchemyDataDriver.map_argst  s[     	% 	%C#v~.. %	****$$$$r8   c                     i }|                                 D ]/\  }}t          |t          j                  r|j        ||<   *|||<   0|S rl   )rF   r  r   r   r  )r5   rK   
new_kwargsr?   r@   s        r6   r<  zSQLAlchemyDataDriver.map_kwargs}  sT    
LLNN 	" 	"DAq!V^,, " !
1 !
1r8   )	no_reloadc                0   |                      |          }|                     |          }|                                 }|                     |j                  } |            }	t          j                    }
|
                    ||	           	 |                    |	           |	                    |	g           n# t          $ rj}|j                                         t          |j        t          j        t"                              rt%          |          |t'          |          |d}~wt(          $ r }|j                                         |d}~ww xY wd|_        |rdS |
                    |	|          }|
                                 d|_        |S )um   
        no_reload - не загружать объект из базы и не возвращать
        objectsNT)
cmf_entity)r;  r<  rH   r   rL   r"   r:  cmf_to_objectr4  flushr	   r   r   r  origr   lookupr   r   r   r   is_newrV  rB  )r5   instancer  rJ   rK   rD  _kwargsr   r   rW  r3  r   rv  s                r6   createzSQLAlchemyDataDriver.create  s    d##//&))LLNN==!344hjj&((X{333	EE+GG[MG**** 	1 	1 	1M""$$$!&&-0@"A"ABB 2'**1&q))q0  	 	 	M""$$$G	  	4"";8"DD  """

s%   ,B: :
EA%D))E6EEc                    |                      |          }|                     |          }|                                 }|                     j                  }t                    j        }|                      t          fd|D                                 }	|                    |          	                    |	          }
	 |
                    |
           n-# t          $ r }|j                                         |d}~ww xY wS )u*   TODO логическое удалениеc              3   8   K   | ]}t          |          V  d S rl   r  r>   fr  s     r6   	<genexpr>z.SQLAlchemyDataDriver.delete.<locals>.<genexpr>  -      'K'K!(<(<'K'K'K'K'K'Kr8   N)r;  r<  rH   r   rL   r   r   r  r   rn   deleter   r   r   )r5   r  rJ   rK   rD  r  r   r   r.  get_argsrW  r   s    `          r6   r  zSQLAlchemyDataDriver.delete  s    d##//&))LLNN==!344H~~)=='K'K'K'Kd'K'K'K!L!LMMggh''++H55	HH[!!!! 	 	 	M""$$$G	 s   C 
D%D  Dc                 D   |                      |          }|                                 }|                    |          }|                     ||          }|r3|                     ||||||          \  }}	|                    |	          }|                    d          }
|
S )Nr'  fetch)synchronize_session)r   rH   r   r  r  r  r  )r5   r  r  r  rK   r   r   r   r  r0  
delete_cnts              r6   bulk_deletez SQLAlchemyDataDriver.bulk_delete  s    ==''LLNN!!''v66 	- $ 7 7eXuoer !8 !t !tE:LL,,E\\g\>>
r8   r'  ro  c                H   ddl m} |                     |          }|                                 }	|	                    |          }
|                     ||          }|r3|                     ||||
||          \  }
}|
                    |          }
|
j        }|
j	        } ||          
                    |                              |j                  }|D ]}|                    |          }|                    |          }|	                    |          }d |D             S )Nr   r  r'  c                     g | ]
}|d          S )r   r   )r>   rR  s     r6   r+  z4SQLAlchemyDataDriver.bulk_update.<locals>.<listcomp>  s    )))3A)))r8   )r0   r  r   rH   r   r  r  r  
_criterion_join_entitiesro  	returningr   rJ  r8  r   )r5   r  ro  r  r  rJ   rK   r  r   r   r   r  r0  filter_criteriajoin_clausesstmtjoin_clauser@  s                     r6   bulk_updatez SQLAlchemyDataDriver.bulk_update  s6   %%%%%%==''LLNN!!''v66 	- $ 7 7eXW\n}FS !8 !U !UE:LL,,E*+vh&&v..88EE' 	1 	1K##K00DDzz/**4))&))))r8   r  )
chunk_sizec                   ddl m} ddlm}m} |sg S |                     |          }|j        }d |j        D             d |j        D             }	 |t                    }
|D ]\}fd|	                                D             }|
t          |                                                                       |           ]d |D             }|                                 }	  ||          }|
	                                D ]\  }}|	t          |          z
  }|r3|D ]0}|D ]+}|dv r |j                    ||<   t!          d	| d
          1t#          dt%          |          |          D ]7}||||z            }|                    |                    |                     8|S # t*          $ r }|j                                         |d }~ww xY w)Nr   r`  )insertr   c                     h | ]	}|j         
S r   r   r   s     r6   r  z3SQLAlchemyDataDriver.bulk_insert.<locals>.<setcomp>  s    222af222r8   c                 \    h | ])}|j         s |j        d k    r|j        |j        "|j        *S r   )r   r   server_defaultrN   r   s     r6   r  z3SQLAlchemyDataDriver.bulk_insert.<locals>.<setcomp>  sI     
 
 
:
"#&D.. (QY-> F->->->r8   c                 $    i | ]\  }}|v 	||S r   r   )r>   r?   r@   
table_colss      r6   rA   z4SQLAlchemyDataDriver.bulk_insert.<locals>.<dictcomp>  s$    AAA$!QjAr8   c                     g | ]
}|d          S r  r   )r>   rs     r6   r+  z4SQLAlchemyDataDriver.bulk_insert.<locals>.<listcomp>  s    '''1qw'''r8   )cmf_created_atcmf_modified_atu   bulk_insert: колонка 'u>   ' NOT NULL без default; передайте значение)collectionsr   r0   r  r   r   r   r   r^   rF   	frozensetkeysr`   rH   r  now
ValueErrorr+  r|   r   ro  r   r   r   )r5   r  ro  r  r   	sa_insertr   r   tblrequired_namesbucketsrR  r  idsr   	base_stmtkeysetrowsneed_addr   r/  batchr   r  s                          @r6   bulk_insertz SQLAlchemyDataDriver.bulk_insert  so   ++++++88888888 	I=='' 22ck222

 
K
 
 
 +d## 	3 	3CAAAA#))++AAAAIaffhh''(//2222'''''LLNN	!	#I ' 7 7)CKK7 W! W W$, W WD#'LLL*2$(**$&0  2VQU  2V  2V  2V  'W  'W  !W	W q#d))Z88 7 7A 1z>!12EIIi..u5566667 J 	 	 	M""$$$G	s   "CF& &
G0GGr%  c          	         ddl m} |                                 }|                     t	                              }t	                    j        }|                     t          fd|D                                 }	i }
t	                    j        	                                D ]b\  }}t          |t          j                  r!t          |t          j                  r<t          |t          j                  rWt          |t          j                  rrt          |t          j                  rt          |t          j                  rt          |t          j                  rt%          |          }t'          |t          j                  r5|j        du s|j        r|j        s	|j        s|                                }|du rt5          dt6           d| d|           ||
|<   |         j        rd|         _        d|
st9          d d	           S  ||                              |
          }|                    t%          ||d                   |	d         k                                  |j                   }	 tC          tE          |#                    |                              d
k    s
J d            n# tH          $ rh}|j%        &                                 t'          |j'        tQ          j)        tT                              rtW                      |tY                      |d }~wt4          $ r }|j%        &                                 |d }~ww xY wS )Nr   r  c              3   8   K   | ]}t          |          V  d S rl   r  r  s     r6   r  z1SQLAlchemyDataDriver.update_v2.<locals>.<genexpr>  r  r8   .u%   Попытка update field=Ellipsis r   FzDEV: warning! UPDATE u*    не содержит изменений.r    uA   Доп.защита, что только 1 объект в update)-r0   r  rH   r   r   r   r;  r  r   rF   r[   r   r   r   r   r   r   r   r  r  r   r  r   
is_changed	orm_dirty	db_formatr   r  r~   ro  r8  r  r   r|   r^   r   r	   r   r   r  r   r  r   r   r   )r5   r  r&  rJ   rK   r  r   r   r.  r  ro  r?   r@   vvr  r   s    `              r6   	update_v2zSQLAlchemyDataDriver.update_v2  s[   %%%%%%LLNN==h00H~~)=='K'K'K'Kd'K'K'K!L!LMMNN)//11 	. 	.DAq!V/00 !V677 !V]++ !V122 !V.// !V011 !V566 1%%B"fn-- $9##rz#} R\ \\^^Syy ]
 ] ]UV ] ]Y[ ] ]^^^F1I{$ .(-% 	^(^^^___Ovh&&v..zz'(DG44CDDNNx{[[	tAIIdOO,,--2224w2222 	0 	0 	0M""$$$!&&-0@"A"ABB 1'))q0&((a/  	 	 	M""$$$G	 s%   =K 
M%A#L88M%M  M%c                   ddl m} |j        r | j        g|R dd i|S |                     |          }|                     |          }|                                 }|                     t                              }t                    j	        }|                     t          fd|D                                 }	|                    |                              |	          }
t          j                    }|                    |
           	 |                    |
g           n# t"          $ rh}|j                                         t)          |j        t-          j        t0                              rt3                      |t5                      |d }~wt6          $ r }|j                                         |d }~ww xY wj        }|                    |
|          }|                                 ||_        |S )Nr   r  r&  c              3   8   K   | ]}t          |          V  d S rl   r  r  s     r6   r  z.SQLAlchemyDataDriver.update.<locals>.<genexpr>V  r  r8   r  )r  r&  )r  rE   ORM_RAW_UPDATE_V2r  r;  r<  rH   r   r   r   r  r   rn   r"   r:  r  r  r	   r   r   r  r  r   r  r   r   r   r   r  rV  rB  )r5   r  r&  rJ   rK   rE   r   r   r.  r  rW  r3  r   r  rv  s    `             r6   r  zSQLAlchemyDataDriver.updateM  s   &&&&&&# 	T!4>(STSSSDSFSSS}}T""((LLNN==h00H~~)=='K'K'K'Kd'K'K'K!L!LMMggh''++H55&((X{333	GG[MG****  	0 	0 	0M""$$$!&&-0@"A"ABB 1'))q0&((a/  	 	 	M""$$$G	 "";8Vf"gg  """

s%   D. .
G8A#FG(GGc                 H    t                                                       d S rl   )rB   before_request)r5   rL   s    r6   r  z#SQLAlchemyDataDriver.before_requestu  s         r8   c                    ddl m} |                                 |                                 t	          j                    }|                                                                  t	          j                    |z
  dk    r0ddl m}m}  ||j	        dt	          j                    |z
              t	          j                    }| j        
                                 t	          j                    |z
  dk    r0ddl m}m}  ||j	        dt	          j                    |z
              t          d	           t                       d S )
Nr   r#  g333333?r  zPROF Session.commit() got r   zPROF Session.remove() got Tnear_commit_or_rollback)r  r$  cache_unlockcache_transaction_startr   rH   r   r  rE   r  remover&   r'   )r5   r$  prof_str  rE   s        r6   r   zSQLAlchemyDataDriver.commitx  sO   ))))))   ))+++)++9;; 3&&77777777K&Z49;;QXCX&Z&Z[[[)++9;; 3&&77777777K&Z49;;QXCX&Z&Z[[[ 	#4@@@@r8   c                     ddl m} t          d           |                                 |                                                                  | j                                         t                       d S )Nr   r#  Tr  )r  r$  r&   r  rH   r   r  r'   )r5   r$  s     r6   r   zSQLAlchemyDataDriver.rollback  sw    ))))))"4@@@@   !!!r8   c                 @     |                                  j        |i |S rl   rH   r   r5   rJ   rK   s      r6   r   zSQLAlchemyDataDriver.query  "    #t||~~#T4V444r8   c                 @     |                                  j        |i |S rl   r  r  s      r6   query_deprecatedz%SQLAlchemyDataDriver.query_deprecated  r  r8   c                    ddl m} |r|d         dk    r|S g }|sj        pg }|                                }|r|}|r
|r|s|dgz  }dt          ffd}|D ]}	d}
|	                    d          r|	d	d
         }	d}
 ||	          }|j        j        d         j        	                    |          }|*|j        j        d         j        	                    |	          }| |j
        D ]}|d         |	k    r
|d         } n|t          d|	 d          ddlm} |j        rt          |j        t"          j        j                  r|dz   }nat          |j        t"          j        j                  r|dz   }n7t          |j        t"          j        j                  r|t-          d          z   }|
rt#          j        |          }|                    |          }|S )u3   Сортировка по логике моделиr   )
QueryProxyz--r   cmf_column_namec                     d}	 |                      d          \  }}}|s|} n|} |r	| d| d}n| d}1|s
j         d}| |  S )Nr;   TrO   rS   _sub_)rl  rb   )r  alias_prefixp1rS   p2r  s        r6   calc_dp_column_namez=SQLAlchemyDataDriver.order_query.<locals>.calc_dp_column_name  s    L	0+55c::	Ar &(O"$ 0&2#>#>R#>#>#>LL&(<<<L	0   5"'/444"5O555r8   F-r    NTr   expru   Не найдено поле uK    или тип поля не поддерживает сортировку.r  r;   )minutes)cmf.data_providers.baser  orderingr   r  r<   r  rK  r   rn   column_descriptionsr   r  rE   ORM_ORDERBY_IDX_SKIPr  r   r0   r'  r   r   DateTimer   descr  )r5   r   r  r  r5  r  r  order_fieldsr  rp   
order_descdp_column_name	dp_columncolumn_descriptionrE   s        `         r6   r  z SQLAlchemyDataDriver.order_query  s   666666  	t++L 	/ >/RL',,..L 	$#L  	#E 	#*: 	#TF"L	6 	6 	6 	6 	6 	6 	6    0	. 0	.CJ~~c"" "!""g!
 1055N(.q1377GGI  !,2157;;C@@	  */*C  &)&1S88$6v$>	 9  !  #S#  #S  #S  #S  T  T  T******* Ainj.>.FGG A )AII	
0@0GHH A )BII	
0@0IJJ A )Ia,@,@,@ @I 7&OI66	NN9--EEr8   c                 J    t                                          |           d S rl   )rB   make_models)rd   rI  rL   s     r6   r  z SQLAlchemyDataDriver.make_models  s!    G$$$$$r8   c                    t          t                    D ]w}t          t          |          }t          |t                    r|j        r4|j        r| j        |j        vrJ|j        s| j        t          k    rb| 	                    |           xdS )u   Создадим схемуN)
dirr   r  r  r   r   data_sourcesr   r   r   )r5   r   re   s      r6   rI   zSQLAlchemyDataDriver.init_meta  s     f++ 	% 	%J
33Ii77 9;M  % $)9;Q*Q*Q) di;M.M.MMM)$$$$	% 	%r8   c                 6   |                                  }t          |                                          }d|                                v rt	          d          |                    d           |                                 | j                            | j	                   t          j                            t          j                    d          }t          |          }|                    d| j        d                    t#          j        |d           d S )Nalembic_versionzDatabase has alembic versionz'CREATE EXTENSION IF NOT EXISTS pg_trgm;zalembic.inizsqlalchemy.urlhead)rH   r   
connectionget_table_namesFileExistsErrorr   r   db_meta
create_allr3   rz   pathr  getcwdr   set_main_optionrE   r   stamp)r5   r   	inspectoralembic_config_filealembic_configs        r6   init_dbzSQLAlchemyDataDriver.init_db
  s    LLNN ALLNN++		 9 9 ; ;;;!"@AAA			;<<<	


,,, gll29;;FF 344&&'7EU9VWWWnf-----r8   c                 B    | j         j                                         d S rl   )r3   pooldisposer4   s    r6   r   z'SQLAlchemyDataDriver.close_all_sessions  s      """""r8   rl   )NTNN)F)NT)FF)NNNN)Mr   r   r   __doc__r   r0   MetaDatar  extdeclarativedeclarative_baser  r   rm   ry   r7   rC   classmethodr  rr   r   r   r   r   r   r   r   r   r
  r   re   r  r  rL  staticmethodre  ro  r   rp  r  r   r  r  ru  r  r  r  r  r  r  r  r1  r^   r  rn   rA  r;  r<  r  r  r  r  r  r  r  r  r  r   r   r   r  r  r  rI   r%  r   __classcell__)rL   s   @r6   r+   r+   !   s        8 O!j!##GN.??& @  M ![]]N= = =>     3 3 [3j   [ ? ? [?* I
 I
 I
 [I
V   N N N( ( ($"d "d "dH9 9 9vO O O $ $ [$L, , ,2 2 2K K K
M M MQN QN QNf K K \K  '  ' \ 'D z*&rssH! ! ! !F  $x.    \.   " D D \D ISei  |A).|B |B |B |B| * * \* & & \&  ( Z Z Z \Z&s sh s s s s< MR\`pu 1 1 1 1 1f +/E$X\T         D 48$ " " " " "H *.QV_cuz  KP     4`= `= `= `=D	     16 " " " " "H  "
 
 
 
 FKZ_ * * * * * * *0 8= / / / / /b ;? ; ; ; ; ;z 8< & & & & &P! ! ! ! !  (  5 5 55 5 5W W W Wr % % % % [%% % %$. . .$# # # # # # #r8   r+   c                       e Zd Zd ZdS )SAModelAccessorc                 h    |dv rd S t                               t          t          |                    S )N)_pytestfixturefunction__test__)r+   r
  r  r   )r5   items     r6   __getattr__zSAModelAccessor.__getattr__!  s1    999F#001F1FGGGr8   N)r   r   r   r7  r   r8   r6   r2  r2     s(        H H H H Hr8   r2  )?rz   r   r  r   r   r   typingr   r   datetimer   sqlalchemy.typesr0   sqlalchemy.ext.declarativesqlalchemy.ormsqlalchemy.sql.selectablesqlalchemy.excr	   r
   r   r   flaskr   r   alembic.configr   alembicr   psycopg2.errorcodesr   psycopg2r   r   cmf.fields.base_fieldsr   r   cmfr   r  r   
base_errorr   r   r   models.base_modelr   r   r   r   baser!   r"   r#   r$   util.immutablesr%   util.cmfutilr&   r'   r(   r)   r+   r2  r   r8   r6   <module>rK     s   				  / / / / / / / /             # # # # # #           ! ! ! !             ) ) ) ) ) ) 0 0 0 0 0 0 0 0 0 0         ! ! ! ! ! !       0 0 0 0 0 0       - - - - - - 6 6 6 6 6 6 6 6             M M M M M M M M M M Z Z Z Z Z Z Z Z Z Z Z Z F F F F F F F F F F F F 0 0 0 0 0 0 J J J J J J J J " " " " " " " " " "|# |# |# |# |#> |# |# |#~?H H H H H H H H H Hr8   