mfpxdZddlmZddlZddlZddlZddlTddlmZddlmZddlm Z ddlm Z dd lm Z dd lm Z dd lm Z dd lmZdd lmZddlmZ ddlmZn #e$rdZYnwxYwGddeZdZdZGddeZGddeZGddeZGddeddZGddeZGd d!eZd"ZdS)#a Lightweight schema migrations. NOTE: Currently tested with SQLite and Postgresql. MySQL may be missing some features. Example Usage ------------- Instantiate a migrator: # Postgres example: my_db = PostgresqlDatabase(...) migrator = PostgresqlMigrator(my_db) # SQLite example: my_db = SqliteDatabase('my_database.db') migrator = SqliteMigrator(my_db) Then you will use the `migrate` function to run various `Operation`s which are generated by the migrator: migrate( migrator.add_column('some_table', 'column_name', CharField(default='')) ) Migrations are not run inside a transaction, so if you wish the migration to run in a transaction you will need to wrap the call to `migrate` in a transaction block, e.g.: with my_db.transaction(): migrate(...) Supported Operations -------------------- Add new field(s) to an existing model: # Create your field instances. For non-null fields you must specify a # default value. pubdate_field = DateTimeField(null=True) comment_field = TextField(default='') # Run the migration, specifying the database table, field name and field. migrate( migrator.add_column('comment_tbl', 'pub_date', pubdate_field), migrator.add_column('comment_tbl', 'comment', comment_field), ) Renaming a field: # Specify the table, original name of the column, and its new name. migrate( migrator.rename_column('story', 'pub_date', 'publish_date'), migrator.rename_column('story', 'mod_date', 'modified_date'), ) Dropping a field: migrate( migrator.drop_column('story', 'some_old_field'), ) Making a field nullable or not nullable: # Note that when making a field not null that field must not have any # NULL values present. migrate( # Make `pub_date` allow NULL values. migrator.drop_not_null('story', 'pub_date'), # Prevent `modified_date` from containing NULL values. migrator.add_not_null('story', 'modified_date'), ) Renaming a table: migrate( migrator.rename_table('story', 'stories_tbl'), ) Adding an index: # Specify the table, column names, and whether the index should be # UNIQUE or not. migrate( # Create an index on the `pub_date` column. migrator.add_index('story', ('pub_date',), False), # Create a multi-column index on the `pub_date` and `status` fields. migrator.add_index('story', ('pub_date', 'status'), False), # Create a unique index on the category and title fields. migrator.add_index('story', ('category_id', 'title'), True), ) Dropping an index: # Specify the index name. migrate(migrator.drop_index('story', 'story_pub_date_status')) Adding or dropping table constraints: .. code-block:: python # Add a CHECK() constraint to enforce the price cannot be negative. migrate(migrator.add_constraint( 'products', 'price_check', Check('price >= 0'))) # Remove the price check constraint. migrate(migrator.drop_constraint('products', 'price_check')) # Add a UNIQUE constraint on the first and last names. migrate(migrator.add_unique('person', 'first_name', 'last_name')) ) namedtupleN)*) CommaNodeList)EnclosedNodeListEntity) Expression)Node)NodeList)OP) callable_) sort_models)_truncate_constraint_name)CockroachDatabasec*eZdZdZdZdZdZdZdS) Operationz/Encapsulate a single schema altering operation.c>||_||_||_||_dSN)migratormethodargskwargs)selfrrrrs H/opt/imunify360/venv/lib64/python3.11/site-packages/playhouse/migrate.py__init__zOperation.__init__s"     cD|jj|dSr)rdatabaseexecute)rnodes rrzOperation.executes! &&t,,,,,rc2t|ttfr||dSt|tr|dSt|t tfr|D]}||dSdSr) isinstancer Contextrrrunlisttuple_handle_result)rresultitems rr'zOperation._handle_results ftWo . . * LL  * * * JJLLLLL u . . * * *##D)))) * * * *rc|j}d|d<t|j|j}|||ji|dS)NT with_context)rcopygetattrrrr'r)rrrs rr$z Operation.runs]!!##!%~ 44 FFDI88899999rN)__name__ __module__ __qualname____doc__rrr'r$rrrrsV99 ---***:::::rrcFtjfd}|S)Ncx|dd}|r |g|Ri|St|jg|Ri|S)Nr+F)poprr.)rrrr+fns rinnerzoperation..inners`zz.%88  -2d,T,,,V,, ,r{???rc |j}t|r |}|dt |dt t |tj| |dS)NzUPDATE z SET T)flat) defaultr rQliteralsqlrr r EQdb_value)rtable column_namefieldr_s r apply_defaultzSchemaMigrator.apply_defaults- W   giiG!!####VE]]##!!Z;''ENN7++    !rcl|dt|S)N ALTER TABLE )r`rar)rctxrds r _alter_tablezSchemaMigrator._alter_tables({{>**..ve}}===rc|||dt|S)Nz ALTER COLUMN rkr`rarrrjrdcolumns r _alter_columnzSchemaMigrator._alter_columns:c5)))**VF^^$$ &rc|}|jdc}|_|j|kr|x|_|_|||d||||_t|tr| |||S)NTz ADD COLUMN ) rQnullrenamerkr`raddlr"ForeignKeyFieldadd_inline_fk_sql)rrdrerfrj field_nulls ralter_add_columnzSchemaMigrator.alter_add_columns!!!&T EJ   + +-8 8EJ* ,sE " " '. ! ! #eiinn    e_ - - /  " "3 . . . rc|||dt |d|S)N ADD CONSTRAINT  rkrQr`rarrrdrs constraints radd_constraintzSchemaMigrator.add_constraints\d//11599+,,VD\\""Z  "rcdd|z}ttdtd|Df}||||S)Nzuniq_%sr<UNIQUEc,g|]}t|Sr2r.0ros r z-SchemaMigrator.add_unique.. sHHHfVnnHHHr)r@r SQLrr)rrd column_namesconstraint_namer~s r add_uniquezSchemaMigrator.add_uniquesl#chh|&<&<< MM HH<HHH I IKLL ""5/:FFFrc|||dt |S)Nz DROP CONSTRAINT r|rrdrss rdrop_constraintzSchemaMigrator.drop_constraintsFd//11599,--VD\\"" $rc|dt|jjjdt t|jjf}|j |d|j z}|j |d|j z}|S)N REFERENCES r{ ON DELETE %s ON UPDATE %s) r`rar rel_model_metarFr rel_fieldre on_delete on_updaterrjrfs rrvz SchemaMigrator.add_inline_fk_sqls''F5?0;<<== $fU_-H&I&I%KLLMM ? &++o?@@C ? &++o?@@C rNcd|d|d|}|dt|dtt |dt t|fdt|dt|d }||d |z}||d |z}|S) Nfk_r<_refs_rirzz FOREIGN KEY r ()rr)rQr`rarrr) rrdrerel rel_columnrrr~rjs radd_foreign_key_constraintz)SchemaMigrator.add_foreign_key_constraint!s1,155+++ssC  ''F5MM""*++F4Z@@AABB(($f[&9&9%;<<==''F3KK   F:&&''    ++o 9::C  ++o 9::C rc |js|jtd|zt|t}|r|jstd||||g}|js@|||||| ||g|rW|j rP| | |||j jj|jj|j|j|js|jrBt+|dd}| |||f|j||S)Nz!%s is not null but has no defaultz$Foreign keys must specify a `field`. index_type)rrr_rZr"rurrxextendrg add_not_nullexplicit_create_foreign_keyappendrrrrFrerrindexuniquer- add_index)rrdrerfis_foreign_key operationsusings r add_columnzSchemaMigrator.add_column8s z Pem3@;NOO O#E?;;  E%/ ECDD D++E;FFG z 8   ""5+u==!!%557 8 8 8  &d> &   //O)4O/OO %% & & & ; C%, CE<66E   dnnU[N-2\5BB C C CrctrNotImplementedError)rrdres rdrop_foreign_key_constraintz*SchemaMigrator.drop_foreign_key_constraint_!!rTc||}|||dt ||r|dd|j|D}||vr|jr||||gS|S)Nz DROP COLUMN  CASCADEcg|] }|j Sr2ro)r foreign_keys rrz.SchemaMigrator.drop_column..ms1FFF  FFFr) rQrkr`rarrget_foreign_keysexplicit_delete_foreign_keyr)rrdrecascaderj fk_columnss r drop_columnzSchemaMigrator.drop_columncs!!  3 & & '/ " " #f[!! " " "  $ KK # # #FF#}==eDDFFF  * $ $)I $44UKHH#N N rc|||dt |dt |S)Nz RENAME COLUMN  TO r|)rrdold_namenew_names r rename_columnzSchemaMigrator.rename_columnushd//11599*++VH%%&&VH%%&&  (rcz||||dS)Nz SET NOT NULLrprQr`rrdros rrzSchemaMigrator.add_not_null~s4t0022E6BB)) +rcz||||dS)Nz DROP NOT NULLrrs r drop_not_nullzSchemaMigrator.drop_not_nulls5t0022E6BB)** ,rcj|}||||d||}|Lt |t st|}|d|}|S)Nz TYPE z USING )rQrpr`ra ddl_datatyper"r rrrdrorfcastrjs ralter_column_typez SchemaMigrator.alter_column_types!! c5&11!!E&&s++,,   dD)) !4yy++i((,,T22C rc|||dt |S)Nz RENAME TO r|rrrs r rename_tablezSchemaMigrator.rename_tablesGd//118<<''VH%%&& (rc |}t||}t| fd|D}t| |||}||S)Nc:g|]}tj|Sr2)r-c)rro table_objs rrz,SchemaMigrator.add_index..s%CCC V,,CCCr)rr)rQrJTableIndexra) rrdrGrrrjrHcolsrrs @rrzSchemaMigrator.add_indexso!!$UG44 %LL CCCC7CCCj)T&NNNwwu~~rc|dt|S)N DROP INDEX rQr`rarrrdrHs r drop_indexzSchemaMigrator.drop_indexs5''VJ''(( *rNNTr)FN)r.r/r0rrrrQ classmethodr\r:rgrkrprxrrrrvrrrrrrrrrrrr2rrrLrLsT"'"'!!!/// @ @[ @ ! !Y !>>>&&& Y(""Y"GGYG$$Y$   =AY,$$Y$L""Y"Y"((Y(++Y+ ,,Y,    Y ((Y( Y**Y***rrLcJeZdZdZedZefdZxZS)rUc|d}|j||z}d|DS)Nai SELECT pg_attribute.attname FROM pg_index, pg_class, pg_attribute WHERE pg_class.oid = '%s'::regclass AND indrelid = pg_class.oid AND pg_attribute.attrelid = pg_class.oid AND pg_attribute.attnum = any(pg_index.indkey) AND indisprimary; cg|] }|d Srr2)rrows rrz;PostgresqlMigrator._primary_key_columns..s4443A444r)r execute_sqlfetchall)rtblquerycursors r_primary_key_columnsz'PostgresqlMigrator._primary_key_columnssB  **53;7744&//"3"34444rcV|d|zS)NzSET search_path TO %s)rQr`)r schema_names rset_search_pathz"PostgresqlMigrator.set_search_paths'0;>?? Arc||}tt|}|||dg}t |dkr|d|dd}d}|j||f}t|r7|d|dd} | ||| |S)NT)r+r<r_seqz SELECT 1 FROM information_schema.sequences WHERE LOWER(sequence_name) = LOWER(%s) ) rsuperrUrrArrboolfetchoner) rrrpk_names ParentClassrseq_namerr new_seq_name __class__s rrzPostgresqlMigrator.rename_tables,,X66.55   $ $Xxd $ K KM  x==A  &.hh  ( LLX ' ' '  * LLV % % % % LLZ ) ) ) : - LL]++ , , , : * LLTZ ) ) )rr)r.r/r0propertyrrrrar2rrrrsw   X   X ""X"rr_Column)rsr rrrr_r ceZdZdZdZdZedZdZdZ edZ dZ edZ ed Z ed Zedd Zed Zd S)rWTc|||dt|S)N MODIFY rmrns rrpzMySQLMigrator._alter_columns9c5))$$VF^^$$ &rc|dt|dt|S)Nz RENAME TABLE rrrs rrzMySQLMigrator.rename_tablesU))VH%%&&VH%%&&  (rc|jd|z}|}|D]}t|}|j|kr|cSdS)NzDESCRIBE `%s`;F)rrrrrs)rrdrerrowsrros r_get_column_definitionz$MySQLMigrator._get_column_definition#se**+;e+CDD    C #&F{k)) *urc|jd||f}|}|std|d|d|dS)NzSELECT constraint_name FROM information_schema.key_column_usage WHERE table_schema = DATABASE() AND table_name = %s AND column_name = %s AND referenced_table_name IS NOT NULL AND referenced_column_name IS NOT NULL;z+Unable to find foreign key constraint for "z " on table "z".r)rrrAttributeError)rrdrerr(s rget_foreign_key_constraintz(MySQLMigrator.get_foreign_key_constraint,ss**3K """" > .). =>> >ayrc|||}|||dt |S)Nz DROP FOREIGN KEY )rrkrQr`rar)rrdre fk_constraints rrz)MySQLMigrator.drop_foreign_key_constraint=s]77{KK d//11599-..VM**++ -rcdSrr2rs rrvzMySQLMigrator.add_inline_fk_sqlErrc|||}|||d|d}t d|j|D}||vr|S||}||||| |||j |j fS)NrFrc3(K|] }|j|fVdSrrrfks r z-MySQLMigrator.add_not_null..P<==YO======r) rrkrQr`radictrrrr dest_table dest_column)rrdro column_defr fk_objects fk_metadatas rrzMySQLMigrator.add_not_nullHs00?? %d&7&7&9&95AA ,,Z^^E^::;;  ==m44U;;=====   # #  ( 00??//*+ --. .rc|||}|jrtd|||d|dS)NzPrimary keys can not be nullrTr)rrrZrkrQr`rars rrzMySQLMigrator.drop_not_null_s{,,UF;; < =;<< <d//11599$$VZZZ--.. 0rcLtd|j|D}||v}|||}|||dt|d||}|rA||}| |||| |||j |j gS|S)Nc3(K|] }|j|fVdSrrr s rr"z.MySQLMigrator.rename_column..kr#rz CHANGE r{)re) r$rrrrkrQr`rarrrr%r&) rrdrrr(rro rename_ctxr)s rrzMySQLMigrator.rename_columnis*==m44U;;===== "Z/,,UH==#|D$5$5$7$7??wz**s6(++,,ws||s6::(:;;<<   $X.K00AA//*+ --  rNcP|td|}|||dt |d||S)Nz5alter_column_type() does not support cast with MySQL.rr{)rZrQrkr`rarrtrs rrzMySQLMigrator.alter_column_types  &'' '!!c5))$$VF^^$$UYYs^^$$  &rc|dt|dt|S)Nrz ON rrs rrzMySQLMigrator.drop_indexsS''VJ''((VE]]##  %rr)r.r/r0rrrpr:rrrrrvrrrrrr2rrrWrWs"&"&&&& ((Y("--Y-   ..Y.,00Y0Y6 & & &Y &%%Y%%%rrWc~eZdZdZejdZejdZejdZejdej Z dZ dZ e dZd Ze dd Ze d Ze d Ze dZe ddZe dZe dZe ddZdS)rYz SQLite supports a subset of ALTER TABLE queries, view the docs for the full details http://sqlite.org/lang_altertable.html z (.+?)\((.+)\)z(?:[^,(]|\([^)]*\))+z ["`']?([\w]+)z FOREIGN KEY\s+\("?([\w]+)"?\)\s+c^|jd|z}d|jDS)Nzselect * from "%s" limit 1cg|] }|d Srr2)rr)s rrz4SqliteMigrator._get_column_names..s444DQ444r)rr descriptionrrdress r_get_column_namesz SqliteMigrator._get_column_namess3m''(Du(LMM44CO4444rc|jdd|g}|S)NzBselect name, sql from sqlite_master where type=? and LOWER(name)=?rd)rrlowerrr4s r_get_create_tablez SqliteMigrator._get_create_tables>m''. ekkmm $&&||~~rc  tdj|D}||vrt d|d|d|\}}j|}j|tj dd|}j | \}}j |} d| D} g} g} g} d}| D]}j| \}||kr||||}|rm| || |j| \}| || |||s*| || |t't)| | }||d }sd }n |krfd }g}| D]^}j|}|)| d |kr ||}|r||_|d z}tjd|ztj}| d|z|}d|}t5t7dt9|gt7|d|dg}t5t7dt9|t=d| Dt7dt?d| Dt7dt9|f}t5t7dt9|g}||| ||gz }tCd|D]u}||j"vr(|t7|j#3r@$|j#|}|"|t7|v|S)Nc3HK|]}|jVdSr)rsr8rs rr"z0SqliteMigrator._update_column..sLFF k''))FFFFFFrzColumn "z" does not exist on ""z\s+r{c6g|]}|Sr2striprcols rrz1SqliteMigrator._update_column..s <<z/SqliteMigrator._update_column..s*rcdSrr2rCs rrDz/SqliteMigrator._update_column..sdrc@jdz|S)NzFOREIGN KEY ("%s") )fk_resub)r' new_columnrs rrDz/SqliteMigrator._update_column..s"djnn% 2//rr__tmp__z ("?)%s("?)z\1%s\2, zDROP TABLE IF EXISTSrrz INSERT INTOc,g|]}t|Sr2rr@s rrz1SqliteMigrator._update_column.. sFFFcfSkkFFFrSELECTc,g|]}t|Sr2rr@s rrz1SqliteMigrator._update_column..sHHH36#;;HHHrFROMz DROP TABLEc|jSr)ra)idxs rrDz/SqliteMigrator._update_column..sr)%setr get_columnsr8rZr9 get_indexesrrerH column_researchgroupscolumn_split_refindallcolumn_name_rematchr startswithr$zipgetrGcompileIr@r rrr?rrrfilterrGra _fix_index)rrdcolumn_to_updater6rG create_tableindexes raw_create raw_columns split_columns column_defsnew_column_defsnew_column_namesoriginal_column_namesconstraint_termsr'renew_column_deforiginal_to_new fk_filter_fncleaned_columnsr\ temp_tablergxcreatequeriespopulate_table drop_originalrrarIs` @r_update_columnzSqliteMigrator._update_columnsDFF$(M$=$=e$D$DFFFFF  ! ! # #7 2 2*...788 8#44U;;|-++E22 &&u---vfc<88 #'."7"7 "E"E"L"L"N"N K,44[AA < >J.44Z@@GGIILK...!#K!:::)00===#'#6#<#<&$($((.!K$++K888&&z222"''))445EFF>$++K888)00===s#8:JKKLL$(()9:: 44  22LL + + +L) 3 3JJ$$Z00E U\\^^A%6:J%J%J)\*55  3&&z222Y& j-rt44  #  ))O,, c0116*3E3EF G G V\\^^^^WWW5 6 68 "    :   FF5EFFF G G MM HH2GHHH I I KK 5MM#!#l"3"3VE]]!CDD       j% 0 02 2//99 - -Eu}44s59~~.... -ooei1A:NN?NN3s88,,,rc||}t|dkr|||S|dd\}}t||dkr|d|||S|dddd}d|D}g}|D]I} t jd|z| r|| t|dz} || J|dd d |DdS) N(rrr,c8g|]}|dS)z"`[]' r>)rparts rrz-SqliteMigrator._fix_index..7s$;;;T4::i((;;;rz%s(?:['"`\]]?\s|$)rKc3 K|] }d|zV dS)z"%s"Nr2)rrs rr"z,SqliteMigrator._fix_index..Bs&)D)D&1*)D)D)D)D)D)Dr)splitrAreplacersplitrUr\rr@) rrardrIr lhsrhsrGcleanros rrczSqliteMigrator._fix_index%sf *++ u::??;;/<< <::c1%%S syy)** + +q 0 0!cc3;;/?#L#L#LM M 3""1%++C00;;U;;;  ! !Fx-0@@&II E#fS1A-B-B-C-C&DD LL 33 )D)De)D)D)D D D D DEErTc2|||dS)NcdSrr2)abs rrDz,SqliteMigrator.drop_column..FsDrry)rrdrers rrzSqliteMigrator.drop_columnDs""5+7H7HIIIrc<fd}||||S)Nc0||Srr)rer'rs r_renamez-SqliteMigrator.rename_column.._renameJs%%k8<< ._add_not_nullPs  + +rr)rrdrors rrzSqliteMigrator.add_not_nullNs) , , ,""5&-@@@rc6d}||||S)Nc.|ddS)Nr rrs r_drop_not_nullz4SqliteMigrator.drop_not_null.._drop_not_nullVs%%j"55 5rr)rrdrors rrzSqliteMigrator.drop_not_nullTs) 6 6 6""5&.AAArNc|td|fd}|||S)Nz6alter_column_type() does not support cast with Sqlite.c}t|\}}|Sr)rtrarr)rer' node_listrar<rorjrfs r_alter_column_typez._alter_column_type`sL #IWWVF^^,,00;;AACCFCJr)rZrQry)rrdrorfrrrjs `` @rrz SqliteMigrator.alter_column_typeZsq  '(( (!!       ""5&2DEEErctrrr}s rrzSqliteMigrator.add_constraintfrrctrrrs rrzSqliteMigrator.drop_constraintjrrctrr)rrdrerfrrs rrz)SqliteMigrator.add_foreign_key_constraintns "!rrrr)r.r/r0r1rUr`rVrYr[rarGr6r9r:ryrcrrrrrrrrr2rrrYrYs ?++I bj!899ORZ 455N BJ:BD A AE555qqYqfFFF>JJJYJ==Y= AAYA BBYB  F F FY F""Y"""Y"=A"""Y"""rrYc8|D]}|dSr)r$)rrr:s rmigraterts*  r)r1 collectionsrr8rBrUpeeweerrrr r r r r rrplayhouse.cockroachdbr ImportErrorobjectrr:rJrLrUrSrrWrYrr2rrrsttj#"""""  ######,,,,,,7777777::::::::6t*t*t*t*t*Vt*t*t*n++++++++\ & & & & &, & & &     **Y)=>>   FI%I%I%I%I%NI%I%I%XU"U"U"U"U"^U"U"U"psAA'&A'