
    *`mhU                       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:  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_eventsc                   `    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dGd	            ZdGd
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&dHdZ'e"dIde(e&         fd            Z)dGdZ*e"d              Z+ej,        dddfd!Z-e"d"             Z.e"d#             Z/d$ Z0e"dJd%            Z1dGd&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/Z6dKd0Z7d1 Z8d2 Z9dd3d4Z:d5 Z;dKd6Z<ddd7d8e=fd9Z>dd:d;Z?dd:d<Z@ fd=ZAd> ZBd? ZCd@ ZDdA ZEdLdBZFe fdC            ZGdD ZHdE ZIdF ZJ xZKS )M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_factoryE   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      r4   
<dictcomp>z1SQLAlchemyDataDriver.__init__.<locals>.<dictcomp>i   sP       Aq<<..		-Q//  r6   )super__init__r.   engine_from_configconfigitemsr1   r/   scoped_sessionr5   Session	init_meta)r3   argskwargs	__class__s      r4   rA   zSQLAlchemyDataDriver.__init__d   s    $)&))) 3K
 
 "LLNN  
 
 "~44T5J5J5L5LMMr6   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)rT   rN   orderno_partition_by_orderno_partition_by_clusterordernoF)r   rD   
issubclassr   indexrN   index_usinglistr   
class_nameappendr.   Index	tablenamehasattrrV   )cls	cmf_modelindexescmf_field_name	cmf_fieldrH   r[   idx_types           r4   __get_indexesz"SQLAlchemyDataDriver.__get_indexesr   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&; &   $)	     r6   c                 r    | j                             |          }|r| j                             |           |S N)cached_queriesgetmove_to_end)rb   keyrets      r4   	get_queryzSQLAlchemyDataDriver.get_query   s>     ""3'' 	0**3///
r6   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 )rk   cached_queries_limitossysconflenpopitemprint)rb   queryrn   sys_memsize_mbchunk_countqueries_limitevicted_keyrQ   s           r4   	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===>>>>> >=r6   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"   Не найден тип поля )rL   r   r   )0r]   virtualrY   r   	CmfBigIntr.   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   	ExceptionrL   )rb   
_cmf_modelrf   _db_field_namecolumn_namesa_typerH   r   s           r4   _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 %'!-
 
 
 	
r6   c                 X    t          | j                                      ||          }|S )N)schema)r   r1   get_columns)r3   
table_namer   columnss       r4   inspect_table_columnsz*SQLAlchemyDataDriver.inspect_table_columns  s)    $+&&22:f2MMr6   c                     |                      |          }| j        j                            | j        |j                  S rj   )dp_modelr1   dialect	has_table	__table__)r3   rc   sa_models      r4   r   zSQLAlchemyDataDriver.has_table  s3    ==++{",,T[(:LMMMr6   c                    |                      d |          j        }t          |t          j                  r| d}t          d           |                                 }d| d| 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   typerY   r   r   r|   rF   r   rL   executecommit)r3   r   r   cmf_field_typesa_column_typessqls          r4   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aZaa;aaQ_aa& 	E%-qaoqqqDD>#9DDDC-...			#,---	


&'''''r6   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.r9   abstract
__module____qualname__u   ID Объекта)captionr   rZ   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 commituB   add_custom_m2m_model Ошбика создания таблицы : )r   Fieldr   	CmfStr256r   r   randomtimesleepuniformr   r|   r.   r   CreateTabler   r   rF   r   r   r   transactionrollback)r3   
model_namerI   rc   r   smtpr   es           r4   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/00000 	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          |t          f|          }|S )NTr   r9   r   u)   Идентификатор объектаu3   Автоматически генерируетсяF)r   commentr   r   readonlyvisibleidr   )r   rZ   nameu   Сортировкаr   )r   rZ   r   r   rL   rX   u   Кодu3   Код в реальном мире из жизни)r   rN   r   r   r   codeu:   Код родителя в каскадном выборе)r   r   r   rZ   choice_parent_idu   Скрыть
cmf_hidden)	r   r   r   r   r   CmfStr64r   r   r   )r3   r   rI   rc   s       r4   gen_custom_choice_modelz,SQLAlchemyDataDriver.gen_custom_choice_modelR  sF   ")RPP|O?I
 
 
t  +
 
 
v
 #LM*
 
 
y  OI
 
 
v &,\OP&
 &
 &
!"  &|N" 
  
  
| i\6::	r6   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   r.   r   r   r   r   rF   r   r   r   r   r   r|   )r3   r   rc   r   r   r   s         r4   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     r4   r?   z5SQLAlchemyDataDriver.dp_model_cls.<locals>.<dictcomp>  s    #B#B#B!AFA#B#B#Br6   )__name__models_registryrl   r`   r   rD   r   r^   extend"_SQLAlchemyDataDriver__get_indexestupleupdater   sa_base_model)rb   rc   r   r   r`   
sa_columnsr   __table_kwargs__re   rf   sa_field_name	sa_columnsa_model_kwargss                r4   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
+r6   c                 ,    |                      |          S rj   )r  )r3   rc   s     r4   r   zSQLAlchemyDataDriver.dp_model  s      +++r6   c                 6    t          t          |j                  S )uG   
        Вернём CMF модель для SA модели.
        )getattrr   r   )r3   r   s     r4   rc   zSQLAlchemyDataDriver.cmf_model  s     vx0111r6   c                 6    t          |t          j                  S rj   )
isinstancer)   r   )r3   dp_instances     r4   is_instancez SQLAlchemyDataDriver.is_instance  s    +';'IJJJr6   c                     i }|D ] }|j         j        ||j         j        j        <   !t          j                            |d|          S )N
table_type)r   r   fullnamer.   r/   polymorphic_union)r3   
cmf_modelsaliastablesmodels        r4   _union_modelsz"SQLAlchemyDataDriver._union_models  sN     	Q 	QE8=8PF5>+455
 ~//eLLLr6   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rj   )KeyErrorr.   r   castnulllabeltype_coerce)r   table
cast_nullscolnamemapstypess     r4   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     r4   
<listcomp>zWSQLAlchemyDataDriver._union_models2.<locals>.hack_polymorphic_union.<locals>.<listcomp>  %    CCC$SSu--CCCr6   from_obj_idc                 (    g | ]} |          S r   r   r&  s     r4   r'  zWSQLAlchemyDataDriver._union_models2.<locals>.hack_polymorphic_union.<locals>.<listcomp>  r(  r6   )r.   util
OrderedSetr  r   Selectr  r   rn   addr   rD   r^   selectliteral_column_quote_ddl_exprr  wherer	  r   correlate_except	union_all)	table_maptypecolname	aliasnamer!  colnamesrn   mr   resulttype_r$  r"  r   r#  left_field_name
left_tablesub_ffls      `      @@@@r4   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Er6   r  )r  T)r   r   r  lateral)r3   r?  right_tabler  r>  right_modelmodels_is_unionr@  rA  	join_subqr;  s    `  `   `   r4   _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Mr6   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@@r   r    r   zInvalid filter operation)r   )paramsop_lists     r4   _parse_paramsz"SQLAlchemyDataDriver._parse_params'  so    \ !9!9fQi22AY'!!!9fQi228&'JJJr6   c                 0   ddl m}m} t          |t          j                  r"|j        du r ||j        d           |j        }nt          |t                    ryt                      }|D ]f}t          |t          j                  r5|j        du r ||j        d           |
                    |j                   Q|
                    |           g|}|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 )Nr   print_debugrC   .u<   collect_filter_exp: Значение не загруженоNULLrJ  rM  rK  rN  )rL  rO  )rQ  rR  rS  rP  r[  r\  rT  rU  rV  rW  rX  )cmf.includerb  rC   r  r   r   _valueDEBUGvaluer\   r^   in_likeilikeop)operfieldvalrb  rC   new_valr>   s          r4   _expressionz SQLAlchemyDataDriver._expression4  sc   33333333c6>** 	zS  FL*hiii)CCT"" 		ffG & &a00 &x3#FL2pqqqNN17++++NN1%%%%C&==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>>#&&&r6   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   Недопустимый тип поля для вложенной фильтрации rM   up   . Вложенная фильтрация возможно только для CmfRelation и CmfGenericRelation_sub__uj   Не возможно построить запрос для вложенной фильтрации по u   , т.к. у поля u#    не указаны related_modelsr   r    r   T)rF  r@  )r]   instance_classr   rl   _raise_invalid_fieldrY   r   r   CmfSubclassedGenericRelationr   related_modelsrz   r.   r/   aliasedr   r   rH  r  rq  )r3   r  r?  
field_name
from_aliasis_models_required	field_clsr@  
alias_partrE  rD  rC  	join_datas                r4   _calc_join_dataz$SQLAlchemyDataDriver._calc_join_datah  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	r6   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  r.   r   
selectableAliasr   )r<   r  s     r4   	<setcomp>z3SQLAlchemyDataDriver._make_joins.<locals>.<setcomp>  sI     /C /C /C%!:!@AA/CJ/C /C /Cr6   r+  )set	statementlocate_all_fromsr  	outerjoinrC  r	  r?  r   r>  r   )r}   r  forceavailable_joinsr  s        r4   _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 r6   c                     d }g }|d }|j         j        }n|j        }|                    d          D ]D}|                     ||||          }|                    |           |j        }|j        }|j        }E|S )NrM   )	r   r   r   splitr  r^   r  rD  rC  )r3   	join_pathr  r?  r{  r  rz  r  s           r4   _calc_joins_by_pathz(SQLAlchemyDataDriver._calc_joins_by_path  s    
J1JJ#J#//#.. 	/ 	/J,,UJ
JWWILL###"J)E".JJr6   c                     t          |j                                      dd          }t          |  d|j         d|           )N,z,
u+    не существует у модели u   , но есть: 
)strr   r;   r   r]   )rz  r  fields_s      r4   rv  z)SQLAlchemyDataDriver._raise_invalid_field  si    el##++C77Z  C  CTYTd  C  C  zA  C  C  D  D  	Dr6   c	           
      n   |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 | 	                    |          \  }}}t          t          |          t                    r|j        }t          t          |          t                    r|j        j        }t          |t          t           f          rg }|D ]}t          t          |          t                    rgt          t          |j                  t                    r%|                    |j        j        j                   p|                    |j                   t          t          |          t                    r |                    |j        j                   |                    |           |}|                    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                   ||                      ||           t          |t$          j                  r!|dv r<t          |t                    s't          |t                     st          d|||          |d	v r|t          d|||          |dv rhddl!m"} | #                    |d||          }|t          d| d          |j$        r|                     tJ          j&                  }|d	v r\|j'        (                    |          )                    |j*        |k    |j+        |j        k              ,                                }|| fS |j-        st|j'        (                    |          )                    |j*        |k    |j+        |j        k    | .                    d |j/        |                    ,                                }n%t          j0        1                    t          j2        3                    |j*        g|g!          4                    |j*                  5                    | .                    d |j/        |                    5                    |j+        |j        k                        }|6                    |t          |j7                  d         |k              }||d k    rt          |j7                  d         d k    nt          |j7                  d         d k    fS |8                                }|                     |          }|j9        r|j:        }|j;        }n'|j<        r|j;        }|j:        }nt          d"||          |d	v rH|j'        (                    |          )                    ||k              ,                                }|| fS |j=        sZ|j'        (                    |          )                    ||k    | .                    d ||                    ,                                }nt          j0        1                    t          j2        3                    |g|g!          4                    |          5                    | .                    d ||                              }|6                    |t          |j7                  d         |k              }||d k    rt          |j7                  d         d k    nt          |j7                  d         d k    fS ||d k    r|n| fS |d#v rE| #                    |d||          }|t          d| d$          | >                    | d d d |%          } | j        }!| j        }"|j'        (                    |"j7        j                  }#|j$        r}|                     tJ          j&                  }$|$j        }%|#                    |%|$j/        |"j7        j        k              }#|#)                    |$j*        |k    |$j+        |j        k              }#n|j<        rd&}&d'}'nd'}&d&}'|8                                }|                     |          }$|$j        }%t          |$|&          }(t          |$|'          })|#                    |%|)|"j7        j        k              }#|#)                    |(|k              }#t          |"j7        d(          r|sg d)}*ng }*t          |"j7        d*          r|s|*g d+g}*|r|*|g}*|                     |*|!|!j        |#|"||          \  }#}*|#)                    |*          }#|#,                                }#|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          d/|||          | #                    |d||          }|t          d| d0          | >                    | d d d |%          }+|+j        },|+j        }-|jB         d1}.t          |-j7        |.          }/|j'        (                    |/          }#|.d2|g}*t          |-j7        d(          r|*g d)g}*|r|*|g}*|                     |*|,|,j        |#|-||          \  }#}*|#)                    |*          }#|#,                                }#|A                    d,          r|# }#||#fS t          |t$          jC                  rg| d1}|d3k    r[| >                    | d d d |%          } | j        }!| j        }"|j'        (                    |"j7        j                  }#|                     tJ          j&                  }$|$j        }%|#                    |%|$j/        |"j7        j        k              }#|#)                    t	          j        | .                    d |$j*        |          | .                    d |$jD        |                    |$j+        d4k              }#| #                    ||||          }|t	          j        | .                    d ||          | .                    d ||#                    fS |dk    rbtJ          jE        F                    |j        ||ddd5g6          }0|0sd7g}0| #                    |d||          }|| .                    d ||0          fS | #                    ||||          }|t          d| d8| d9          || .                    |||          fS ):Nr   )field_tableinclude_deletedinclude_dummyANDr    OR)cmdr  r  r  order_by   )rO  rL  ut   Операция order_by в фильтре должна быть в формате: ["order_by", "=", [поля..]]r   r  rM   FrY  )r?  TANYr\  r   u	   Поле u    не найдено у )rP  rT  u   Правое значение для IN, NOT IN для m2m должно быть list, т.е. в квадратных скобках, например "field", "IN", "[obj.id]"u   Недопустимая операция над m2m полем (сравнение = только на None), допустимые IN, NOT IN, = None)rP  rT  rO  rL  rC   
with_aliasu   В таблице u3    нет поля id для фильтрации m2mrP  r)  uD   Надо указать для поля либо left либо right)rY  rZ  uG    нет поля id для фильтрации в подзапросе)r}  r   r   cmf_deletedr  rL  Fis_dummyr  rL  FzNOT uh   Недопустимая операция над m2m полем, допустимые IN, NOT IN, = NonerZ  ul   Недопустимая операция над backref полем, допустимые EXISTS, NOT EXISTSu7    нет поля id для фильтрации backrefr+  rL  r[  
rg_membersi'  )r   rz  search_queryonly_idssliceNOTFOUNDu    нет поля u    для фильтрации)Gr  r\   collect_filter_expr^   r.   or_rz   r   order_queryr_  rY   r   r   rg  r   r   r   r  r   rl   
CmfM2MBaser   r   joinr   r   
rpartitionr  r  rD  rC  r]   rv  rd  rC   _query_columnnested_fieldsr   RelationCachesessionr}   filter	parent_idparent_fieldexistsORM_RELCACHE_EXISTS_VIA_JOINrp  child_idr/   ry  r   r1  distinctr4  r  r   m2m_model_clsrightr   r   leftORM_M2M_EXISTS_VIA_JOINr  r	  ra   r:   backrefCmfRelationBaseparent_codeCmfFullSearchfulltext_search)1r3   	in_filterr  r   r}   r  r  r  r  
filter_resr>   exprl  r  r  _righti
left_partsr}  r  r  rQ   r  r  rC   field_column	m2m_modelm2m_subquery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	found_idss1                                                    r4   r  z'SQLAlchemyDataDriver.collect_filter_exp  sw     t	F$;	!d++ r	F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$; !% 2 29 = =D$$u++w// $$u++y11 '%$//   
) 
)A!$q''733 	)%d17mmY?? 3"MM!'**:;;;;"MM!'2222#DGGY77 )adj1111a(((( CJ((A77IJ:"""9v/@&BSU[Um.noo # "!}*QRR.114?&"'.":KZ1$$%)__S%9%9"	1d00Ek0ZZ((66!"I	!-!L,,T22	'3!

&"'.":K
 u}}!L,,T22	 `!"^d"^"^EL\"^"^___ ))$666)V%677 Cb+++Zt5L5L+PZ[`bgPhPh+% K  MQ  SX  Zcd d d ;&&u}% q  sw  y~  @IJ J J 666222222#'#5#5k4[e#5#f#fL#+)*{***  A  A  A . ?C %)MM&2F$G$G	;..+0=+>+>y+I+I+P+P ) 3| C ) 6):N N,P ,PPVPVPXPX ) $)<-#77#)#F C/4}/B/B9/M/M/T/T$-$7<$G$-$:i>R$R$($4$4T9;Mu$U$U0W 0W X^W]W_W_ !-
 0:~/E/EjnF[F[%.%8$9YK G\ G" G""*(9+>"?"?dFVFVW[]f]oqvFwFw@x@xy~y~(1(>)BV(VzX zX0Y 0Y
 ).d<>FZFZ[\F]amFm(n(n',QUY]Q]Q]d<>.B.B1.E.M.Mcghthvcwcwxycz  C  dC  (C  !C %.$;$;$=$=	'+}}Y'?'?$? H0<0E-1=1E..&^ H0<0D-1=1F.."-.tv{  ~G  #H  #H  H;..+0=+>+>|+L+L+S+S 1\ A,C ,CCI688 )#(<-#77#)#A C/4}/B/B</P/P/W/W$5$E$($4$4T;Mu$U$U0W 0WW]W]W_W_ !- 0:~/E/EjnF[F[%6$7<. G\ G" G""*(+<"="=eeDDTDTUY[motDuDu>v>v0x 0x ).d<>FZFZ[\F]amFm(n(n',QUY]Q]Q]d<>.B.B1.E.M.Mcghthvcwcwxycz  C  dC  (C  !C $$,,,,\MQQ333"&"4"4[$Zd"4"e"eK"*)  +T{  +T  +T  +T  U  U  U  $33D$dV_3``H ( 4I ( 4I % 3 3IKN C CI . Q (,}}V5I'J'J$0$:	$-NN9l>SW`WbWe>e$f$f	$-$4$4(2kA(59MM%O %O		 %> :/8,0:--/9,09-$-$;$;$=$=	'+}}Y'?'?$0$:	&-l<L&M&M'.|=N'O'O$-NN9likn>\$]$]	$-$4$4[K5O$P$P	y{M:: ,? ,)E)E)E)+y{J77 U U*8:S:S:S)T A*8%)@040G0G&	93Ey^g  zI&3 1H 15 15-I~ !* 0 0 @ @I ) 0 0 2 2Iv.. /%.J	 )++ & C  EI  KP  R[\ \ \I(96;S'TUU 5b++++/??6+B+BP<<D!4/E777% GeY0 0 0 #00dEV`0aa&%&;&&&  A  A  A  $33D$dV_3`` , 8 , 8)2):&?&?&?#!(:M!N!N!M//??	"5t[!I=?M:: T&46R6R6R%SN =&4e%<N,0,C,C"M=3I9bo  BQ"/ -D -1 -1)	> &,,^<<	%,,..	??6** +!*
Ii''Iv'=>> b|||;&&#33D$dV_3``H ( 4I ( 4I % 3 3IKN C CI#'==1E#F#FL , 6I )y,:OS\S^Sa:a b bI ) 0 0"t'7'7l>TV['\'\'+'7'7l>VX]'^'^` `$1\A!C !CI $(#5#5k4[e#5#f#fL *.1A1A$V[1\1\151A1A$V_1`1`#b #b b b t||"0@@EL\LPNSJNHI5z	 A S S	
 ! -!+I#11+tUWa1bbd..t\9MMMM  --k4S]-^^L#!"w{"w"wUY"w"w"wxxx$**4uEEEEr6   c                     |  dS )N_m2m_directr   rz  s    r4   _m2m_depth_alias_namez*SQLAlchemyDataDriver._m2m_depth_alias_name  s    ))))r6   c                     |  dS )N_m2m_idr   r  s    r4   _m2m_alias_namez$SQLAlchemyDataDriver._m2m_alias_name  s    %%%%r6   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   rL  )	rl   r  r  r   loadsr\   rD   r   r^   )r3   r  rI   smart_filterr=   r>   s         r4   _get_filterz SQLAlchemyDataDriver._get_filter  s     zz(B//lC(( 	4:l33L 	
<?D A A 	L LLNN 	2 	2DAqEL  ##QaL111r6   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=Falsert  )sumavgcountminmaxNrM   )r  r  r  r.   r   r  r  r   r  r	  r   r   r  r  r;   )r   r   r}   r  from_	func_namecolumn_name_shortcolumns           r4   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 r6   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   rl   rY   r   r   rw  )r<   related_modelr}  rz  s     r4   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r6   r   F)r|  r@  )r  )rC  r   r   rD   r  boolr^   right_modelsru  r  r  _select_joined_columnsrD  )r3   fflr  r   r  r  r   r@  r  rx  
fields_cls
left_modelr{  r  r}  rz  s                 @@r4   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r6   )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   rF   rd  r  hashr   r   rp   _clonewith_sessionr   r  r}   r  r   rz   r   ranger  r  r  r   r   r^   r  )r3   r  r
  r  r  r  rH   rI   r   r   r  rn   r}   start_calc_timer  r   clone_qpkeyr  r  
filter_expr   s                         r4   _create_queryz"SQLAlchemyDataDriver._create_queryA  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r6   )
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  r  )r  r  r  simpler
  r  r  )r  r"   
get_mappermap_args
map_kwargsr  with_labelsr  r  alllist_to_cmfwith_for_update	_load_m2mpost_mapping_hook)r3   r  r  r
  r  r  r  r  r  r  r  r  rH   rI   mapper_is_my_argsqsql_resres_objss                      r4   r\   zSQLAlchemyDataDriver.listt  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 /,,...Or6   )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 )r  r
  c                 4    g | ]}j         j        |         S r   )r   r   )r<   r   r   s     r4   r'  z.SQLAlchemyDataDriver.count.<locals>.<listcomp>  s$    UUU[x)+K8UUUr6   Nr  r  )r  r  r  r   r   r  select_fromfromswith_only_columnsr   r  r  r  r\   r  r   	enumerater^   scalar)r3   r  r
  r  rH   rI   r'  r(  r   count_qres_listresrowrow_resr  r   r  r   s                    @r4   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r6   )r  r
  r  r  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  r  )r  r  r  N)r  r"   r  r  r  r  r   r  r#  firstobject_to_cmfr$  r%  )r3   r  r  r
  r  r  r  r  rH   rI   r&  r(  sa_instanceres_objs                 r4   rl   zSQLAlchemyDataDriver.get  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	 	r6   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 rj   )r   re  )obj_is_heavys    r4   obj_idz.SQLAlchemyDataDriver._load_m2m.<locals>.obj_id  s     &w~%7Nr6   c                  &    d } t          |           S )Nc                  *    t          t                    S rj   )r   r\   r   r6   r4   id_to_list_factoryzWSQLAlchemyDataDriver._load_m2m.<locals>.model_to_id_factory.<locals>.id_to_list_factory  s    "4(((r6   )r   )rC  s    r4   model_to_id_factoryz;SQLAlchemyDataDriver._load_m2m.<locals>.model_to_id_factory  s     ) ) )1222r6   .u#   Не загружено id поле:r   r   rP  )r
  r  r  r  r+  c                 &    g | ]} |          S r   r   r<   or@  s     r4   r'  z2SQLAlchemyDataDriver._load_m2m.<locals>.<listcomp>f  s!    :W:W:W66!99:W:W:Wr6   r  r  r  r  )r
  r  r  r  r  ra  zORM: skip load field rM   z die no related modelsr    c                 $    i | ]\  }}||j         S r   )r  )r<   r=   r;  s      r4   r?   z2SQLAlchemyDataDriver._load_m2m.<locals>.<dictcomp>  s      M M MDAqAK M M Mr6   r  r   r   c                 &    g | ]} |          S r   r   rG  s     r4   r'  z2SQLAlchemyDataDriver._load_m2m.<locals>.<listcomp>  s!    0M0M0Mq0M0M0Mr6   F)r
  r  r  r  )6r  r#   r   r\   r^   r]   r	  r   rY   r   r   r  r  CmfBackrefBaserD   rl   re  _oldid_fieldnamer   setattr	partitionr$   r$  r  dictr%   rx  r  r  r`   rd  rb  rC   rf  rz   nextitervaluesr!  r}   r.   r/   r  r"  r   r   r  r  r   r  rh  ra   apply_changes)?r3   objsr
  r  r  r  rD  to_load_mappingmy_objs_by_idmy_objs_by_model_namemodels_by_rel_fieldsobjr   r  rz  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_filterr(  rb  rC   r3  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?                                                                @@r4   r$  zSQLAlchemyDataDriver._load_m2m  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\=]	= ]	=r6   c                     g }|D ]L}t          |t          j                  r|                    |j                   7|                    |           M|S rj   )r  r   r   r^   rg  )r3   rH   new_argsargs       r4   r  zSQLAlchemyDataDriver.map_args  s[     	% 	%C#v~.. %	****$$$$r6   c                     i }|                                 D ]/\  }}t          |t          j                  r|j        ||<   *|||<   0|S rj   )rD   r  r   r   rg  )r3   rI   
new_kwargsr=   r>   s        r4   r  zSQLAlchemyDataDriver.map_kwargs  sT    
LLNN 	" 	"DAq!V^,, " !
1 !
1r6   )	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  rF   r   rJ   r"   r  cmf_to_objectr0  flushr	   r   r   r  origr   lookupr   r   r   r   is_newr9  r%  )r3   instancer  rH   rI   r'  _kwargsr   r   r:  r  r   rZ  s                r4   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 rj   r	  r<   fr  s     r4   	<genexpr>z.SQLAlchemyDataDriver.delete.<locals>.<genexpr>4  -      'K'K!(<(<'K'K'K'K'K'Kr6   N)r  r  rF   r   rJ   r   r   r   r}   rl   deleter   r   r   )r3   r  rH   rI   r'  r  r   r   r  get_argsr:  r   s    `          r4   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   rF   r}   r  r  r  r  )r3   r  r  r  rI   r   r   r}   r  r  
delete_cnts              r4   bulk_deletez SQLAlchemyDataDriver.bulk_delete=  s    ==''LLNN!!''v66 	- $ 7 7eXuoer !8 !t !tE:LL,,E\\g\>>
r6   r  rS  c                H   ddl m} |                     |          }|                                 }	|	                    |          }
|                     ||          }|r3|                     ||||
||          \  }
}|
                    |          }
|
j        }|
j	        } ||          
                    |                              |j                  }|D ]}|                    |          }|                    |          }|	                    |          }d |D             S )Nr   r   r  c                     g | ]
}|d          S )r   r   )r<   r5  s     r4   r'  z4SQLAlchemyDataDriver.bulk_update.<locals>.<listcomp>_  s    )))3A)))r6   )r.   r   r   rF   r}   r  r  r  
_criterion_join_entitiesrS  	returningr   r-  r4  r   )r3   r  rS  r  r  rH   rI   r   r   r   r}   r  r  filter_criteriajoin_clausesstmtjoin_clauser<  s                     r4   bulk_updatez SQLAlchemyDataDriver.bulk_updateI  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))&))))r6   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 rj   r  r  s     r4   r  z1SQLAlchemyDataDriver.update_v2.<locals>.<genexpr>g  r  r6   .u%   Попытка update field=Ellipsis r   FzDEV: warning! UPDATE u*    не содержит изменений.r    uA   Доп.защита, что только 1 объект в update)-r.   r   rF   r   r   r   r  r   r   rD   rY   r   r   r   r   r   r   r   r	  r  r   re  r   
is_changed	orm_dirty	db_formatr   r  r|   rS  r4  r  r   rz   r\   r   r	   r   r   r  r   r  r   r   r   )r3   r  r
  rH   rI   r   r   r   r  r  rS  r=   r>   vvr  r   s    `              r4   	update_v2zSQLAlchemyDataDriver.update_v2a  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 rj   r  r  s     r4   r  z.SQLAlchemyDataDriver.update.<locals>.<genexpr>  r  r6   r  )r  r
  )rd  rC   ORM_RAW_UPDATE_V2r  r  r  rF   r   r   r   r   r}   rl   r"   r  r  r  r	   r   r   r  r  r   r  r   r   r   r   r  r9  r%  )r3   r  r
  rH   rI   rC   r   r   r  r  r:  r  r   r  rZ  s    `             r4   r   zSQLAlchemyDataDriver.update  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 rj   )r@   before_request)r3   rJ   s    r4   r  z#SQLAlchemyDataDriver.before_request  s         r6   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?ra  zPROF Session.commit() got r   zPROF Session.remove() got Tnear_commit_or_rollback)rd  r  cache_unlockcache_transaction_startr   rF   r   rb  rC   rf  remover&   r'   )r3   r  prof_strb  rC   s        r4   r   zSQLAlchemyDataDriver.commit  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@@@@r6   c                     ddl m} t          d           |                                 |                                                                  | j                                         t                       d S )Nr   r  Tr  )rd  r  r&   r  rF   r   r  r'   )r3   r  s     r4   r   zSQLAlchemyDataDriver.rollback  sw    ))))))"4@@@@   !!!r6   c                 @     |                                  j        |i |S rj   rF   r}   r3   rH   rI   s      r4   r}   zSQLAlchemyDataDriver.query  "    #t||~~#T4V444r6   c                 @     |                                  j        |i |S rj   r  r  s      r4   query_deprecatedz%SQLAlchemyDataDriver.query_deprecated  r  r6   c                    ddl m} 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   )
QueryProxyr   cmf_column_namec                     d}	 |                      d          \  }}}|s|} n|} |r	| d| d}n| d}1|s
j         d}| |  S )Nr9   TrM   rQ   _sub_)rO  r`   )r  alias_prefixp1rQ   p2r  s        r4   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5r6   F-r    NTr   expru   Не найдено поле uK    или тип поля не поддерживает сортировку.r  r9   )minutes)cmf.data_providers.baser  orderingr   r  r:   r  r.  r   rl   column_descriptionsr   rd  rC   ORM_ORDERBY_IDX_SKIPr  r   r.   r#  r   r   DateTimer   descr  )r3   r}   r  r  r  r  r  order_fieldsr  rn   
order_descdp_column_name	dp_columncolumn_descriptionrC   s        `         r4   r  z SQLAlchemyDataDriver.order_query  so   666666  	/ >/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r6   c                 J    t                                          |           d S rj   )r@   make_models)rb   rE  rJ   s     r4   r  z SQLAlchemyDataDriver.make_modelsC  s!    G$$$$$r6   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   )r3   r   rc   s      r4   rG   zSQLAlchemyDataDriver.init_metaH  s     f++ 	% 	%J
33Ii77 9;M  % $)9;Q*Q*Q) di;M.M.MMM)$$$$	% 	%r6   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)rF   r   
connectionget_table_namesFileExistsErrorr   r   db_meta
create_allr1   rx   pathr  getcwdr   set_main_optionrC   r   stamp)r3   r   	inspectoralembic_config_filealembic_configs        r4   init_dbzSQLAlchemyDataDriver.init_dbZ  s    LLNN ALLNN++		 9 9 ; ;;;!"@AAA			;<<<	


,,, gll29;;FF 344&&'7EU9VWWWnf-----r6   c                 T    t                       | j                                         d S rj   )r   r1   disposer2   s    r4   r   z'SQLAlchemyDataDriver.close_all_sessionsl  s(    r6   rj   )NTNN)F)NT)FF)NNNN)Lr   r   r   __doc__r   r.   MetaDatar  extdeclarativedeclarative_baser   r   rk   rw   r5   rA   classmethodr   rp   r   r   r   r   r   r   r   r   r  r   rc   r  r  rH  staticmethodr_  rp  r   rq  r  r   r  r  rv  and_r  r  r  r  r  r  r  r\   r  rl   r$  r  r  r  r  r  rP  r  r  r   r  r   r   r}   r  r  r  rG   r  r   __classcell__)rJ   s   @r4   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1 1 1fO O O $ $ [$L, , ,2 2 2K K K
M M MQN QN QNf 
K 
K \
K /' /' \/'b z*&rssH! ! ! !F  $x.    \.   " D D \D ISei  |A).xF xF xF xFt	 * * \* & & \&  ( 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 ;? ; ; ; ; ;z 8< & & & & &P! ! ! ! !  (  5 5 55 5 5V V V Vp % % % % [%% % %$. . .$      r6   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   )r3   items     r4   __getattr__zSAModelAccessor.__getattr__r  s1    999F#001F1FGGGr6   N)r   r   r   r  r   r6   r4   r  r  q  s(        H H H H Hr6   r  )=rx   r   collectionsr   r   r   typingr   r   datetimer   sqlalchemy.typesr.   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   rd  r   
base_errorr   r   r   models.base_modelr   r   r   r   baser!   r"   r#   r$   util.immutablesr%   util.cmfutilr&   r'   r)   r  r   r6   r4   <module>r     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N N N N N> N N Nb:H H H H H H H H H Hr6   