PostgreSQL Part.11©2ch.net
レス数が1000を超えています。これ以上書き込みはできません。
Cとの型変換が必要かどうかで違いがあるんじゃないの?
charじゃなく”char”ならOKとか Postgresの文字列型はtext型とみなす仕様が根底にある。
同じ文字データ型でもキャストがうまくいかないのがはまるところ。 >>931
ありがとうございます!
今まで色々やってみてまだ出来ていないです…
明日やってみます! >>932、933、934、935
ありがとうございます!
明日も色々やってみます。 やっぱりECPGの実行体起動すると以下で落ちちゃいますね…
[malformed array literal: "" on line 53][-400] zip版ダウンロードしたら、pgAdmin4のフォルダ名が長すぎて解凍失敗するわ。
こないだまで解凍出来たのに。
インストーラー使ってインストールしたらアンインストール中にエラーになるわ。
255文字制限解除しないと使えないのが普通だっけ? >>939
プラットフォーム名が書かれていないし、「255文字制限解除」が何か分からないので外すかもしれんが、
インストール先のファイルシステムはサポートされているもの?
仮にWindowsとした場合、FATやFAT32はサポートされていない。
それから、これは未確認だけど、もし新しいZIP64フォーマットが採用されてるなら、対応するアーカイバを使うとか。
パーミッション、あるいは空き容量が不足していて伸長が正しくできない可能性は? zip解凍できないのはpostgre以前にOSの問題だね。 問題ではなく、仕様やろ。
C:¥ルートにでも展開すりゃええんちゃうの? 少しお聞きしたいのですが
現在社内にある旧商品管理鯖(引退済み)のマシンを引っ張り出してきたのですが
PostgreSQLのVerが7.3.10でした。
この状態からpg_dumpallでデータを取り出すことは出来たのですが、
別のサーバにPostgreSQLのVer12をインストールして、
イカのコマンドを打ったところ、
psql -U postgres -f /backup.db > update.log
画像の様な状態になってどうしたものかと考えております。
エラーでキーが重複してることや、
multiple primary keys for table are not allowedのように
複数の主キーは許可されていませんと出てきているのですが、
これは、SQLのバージョンを一気に上げすぎているからなのでしょうか?
それとも、データベース自体が壊れている可能性があるのでしょうか?
(過去に鯖の半クラッシュが何度かあった模様)
よろしくお願いします。
https://i.imgur.com/daRuFqr.jpg
https://i.imgur.com/pCXROZr.jpg 自分なら、その方法がサポートされているか(バージョン間、手順)を調べて、
サポートされているようならログを見て起こっている問題・原因を把握したうえで対策を考える。 duplicate key value violates unique constraintとかあるようだけど、DBに既にテーブルがあったりしない? 初心者ですみません。既存TBLにカラム追加してレングス変わると影響大きいですか?当初TBL設計時にFILLER積んだほうが良いのでしょうか? 仕事で使ってるけど必要になったらカラムどんどん追加してるよ そんなのプログラムの作りによるんじゃないの
DBに依存しまくってると苦労する >>946
メインフレームのファイルのようなものじゃなくて、データファイルの内部は頻繁にデータの位置を変えている。
そんな古風な仕組みではない。 外部キー制約を一時的に変更するにはどうすればいいでしょうか?
通常は、ON UPDATE RESTRICT で、一時的に ON UPDATE CASCADE にしてクエリ実行後に RESTRICT に戻すにはどうすればいいのでしょうか?
ADD CONSTRAINT と DROP CONSTRAINT の方法は分かるのですが・・・ ALTER TABLEのALTER CONSTRAINTではできないのでDROP/ADDする
ALTER TABLE <table_name>
DROP CONSTRAINT <fk_name>,
ADD CONSTRAINT <fk_name> FOREGIN KEY … ON UPDATE CASCADE; 物理外部キーを作るくらいなら、論理外部キーとしておいた方が楽。
ガチガチにしておいても、エラーハンドリングの実装がなければ意味がない。 update on conflictを使いまくってるとシーケンス値が上がりまくって、primary keyのidの値が飛びまくるんだけど
気にしたら負けかな。
もちろん綺麗に1 2 3とならない事は認識してるけど、1 1235 5493 29849 みたいに膨大な数飛びまくると…。
99%がupdateの場合なんだけど、update returningして件だったらinsertにした方がいいのかな
その場合ロックとか考えなきゃいけないのが大変なんだけど、もう避けられないのかな insert on conflict do update(いわゆるupsert)のことだよね?
conflictの条件をprimary keyにできないならPKのシーケンスが飛びまくるのはしょうがないと思う
ただ99%がupdateならupdateしてからinsertのほうが性能は良くなるような気がする
ロックを考えなきゃいけないというのはよくわからない
今も同じじゃない? 言いたいのはロックじゃなくてトランザクションじゃないかな >>957-958
ありがとうございます。
on conflict do updateであれば、トランザクション貼らずともコマンドを実行するだけで確実にinsertかupdateが確定で成功するけど
update → insertだと両方updateが0件になって両方insertしようとして片方がエラー という事が起きるかなと認識していました update → insert on conflict do updateをトランザクションでくくれば今と同じなんじゃないかな
ただREAD COMMITEDならlost updateが発生してるだろうから
本当にそれが望ましいのかよく考えたほうがいいと思う insert into 〜 on conflict do updateでシーケンス値が増えるのが我慢できなくて
insert into 〜 on conflict do update相当の処理をトランザクションで書いているのですが
これって最終的にテーブルに対してACCESS exclusiveロック(selectすら妨害する最強ロック)をかける事が必須だったりしますか?
上記のクエリと同じ処理を行いたい場合、以下の処理を行う必要があると思います
・select文で該当の行が既にあるかをチェック
・select文の結果を見て、該当の行があればupdate
・select文の結果を見て、該当の行が無ければinsert
トランザクション1と2が両方同じタイミングでselect文を発行して、どっちもresultが0だった場合、どっちもinsertをしようとしてしまう。
だからどちらか片方のselect文は、他のinsertが終わるまで待ってから行って、result 1を取得する必要がある。
最初は行ロックでいいかな?と思ったのですが、最初にselectをした段階で対象の行は「存在しない」ので行ロックがかけれません。
となると、対象のテーブルに一番強い権限のACCESS exclusiveロックをかける必要がある?と思います。
ですが、それだとdo updateとは無関係のただのselect文に対してもロックがかかってしまいます。
この一連のdo update〜の処理でだけ排他ロックをかけたいのですが、そんな事出来るのでしょうか? 違った。
SHARE UPDATE exclusiveモードを使えばよかったのか
失礼しました 同じ話題を引っ張り続けて申し訳ないけど、自分でinsert〜on conflict do update(upsert)相当の事をするのが面倒すぎて、趣味ですら面倒で手が止まる。
仕事じゃ絶対提案出来ないな(ダルすぎて)
自分の場合は実際には1000件単位のデータをupsertしてるんだけど、この数だと1件づつselect→(update or insert)は遅すぎる。
select文で1000件のデータのユニークキーに対して長いwhere 文を作る。
( SELECT id,key FROM tbl WHERE key in ( $1 , $2 , $3 .... , $1000) )
select文の結果を入れたい1000件単位のデータと比較して、1件づつinsertするかupdateするかを判定する
insert、updateも1件づつやるとトランザクションしても遅いから1リクエストで済むように動的にクエリ文を作る。
( INSERT INTO tbl (key) VALUES ($1),($2)... )
( UPDATE tbl SET key=c.key FROM( VALUES ( ($1,$2),($3,$4),...) AS c(id,key) WHERE tbl.id=c.id )
そしてupsertから加えた機能で、含まれてないデータをDELETEもするようにしてるからさらにクエリ文が増える。
SQL文の文字列をプログラムから動的に作るんじゃなくて、
O/Rマッパーというのを使ってもっと構造的に出来るようにするべきなんだろうか…。
ちなみにnode.jsです。 その1000件とかの入力データに同じユニークキーを対象としたデータがあった場合にどうしたいの?
何か累積値や合計値を計算してて必ずカウントアップしていかないといけないとか
入力データ内の順序で後のデータを正として先のデータは捨てられてもいいとか
>>962
>SHARE UPDATE exclusiveモードを使えばよかったのか
これだとテーブルロックになるので1つのトランザクションが終了するまで次のトランザクションは待つことになる
これで十分なユースケースならそもそも同じキーに対して同時にinsertが実行される心配しなくてもいいよね?分離レベルをSerializableにすれば該当キーがロックされるだけで済むはず ごめんなさい、SQLクエリについてはSHARE UPDATE exclusiveのロックを取得する。で何の問題もありません。
自分が今悩んでいるのは、SQL文が動的になって書くのが大変という事です。
1000件あるデータ以下のような1回のinsert文で全ての値を登録するなどの事をしています。
insert into tbl (key1,key2,key3) values(1,2,3),(4,5,6),(7,8,9);
nodejsの場合、プログラムの中からSQLを実行する時は以下のような書き方をするのですが
query(`insert into tbl(key)values($1)`,[1]);
これが可変になると、以下のような書き方になってものすごく読みにくく感じます。実際はパラメーター複数あってさらに複雑ですし。
query(`insert into tbl(key)values ${insertDatas.map((v,i)=>`($${i+1})`).join(",")}`,insertDatas);
もちろんプログラムとしては全く難しくないのですが、素直に言ってダルい。$が連続しているのも読みにくさが増す理由になってる。
なので、こういう場合はO/Rマッパーというものを使えば
文字列操作ではなく見やすい書き方になったり
1回頑張って作れば他のテーブルに横展開出来るから楽なのかな?という趣旨でした。
言語化するとposgresqlのスレで言う事じゃない気もして、申し訳ない。 ORMじゃなくてもbulk insert用のSQLを生成/フォーマットする機能のあるライブラリを選べばいいよ
>query(`insert into tbl(key)values ${insertDatas.map((v,i)=>`($${i+1})`).join(",")}`,insertDatas);
string interpolationに入れた場合に適切にエスケープしてくれるのかどうかちょっと怪しくない? ストアドファンクションでINSERTしたレコードを取得するにはどうすればいいでしょうか?
INSERTは下記のクエリで行っています。
RETURNS VOID になっている所を、RETURNS TABLEにしてレコードを取得したいのですが、具体的なソースコードが思いつきません。
https://ideone.com/5JPpQ4 >>968
解決した方法も書いておけよ。そうすることでQ&Aが成り立つし、次に困ったときに返信があることが期待できるようになるんだぞ。 RETURNINGやろ
それ以外で自決してたら知らん 解決した方法は下記です。
RETURNS TABLE - RETURN QUERY です。
https://ideone.com/kgQo96
もっといい方法もあると思いますが、自分では思い付きませんでした。 初心者はわかっている値を再度、SELECTしたりするよな。 すみません。
どこが悪いのでしょうか。
RETURN QUERY SELECT については、
使用時はプログラムで INSERTINCIDENT() に引数(incident_name, full_text, registered_by) を与えて呼び出し、
プログラムで与えた引数の値と、INSERT された値が一致するかどうかを比較する必要があるので、意図して SELECT しています。 ネタじゃなければ、確認することをくっつけて実行するのは素人だと思ってください。
そもそもincident_nameとfull_textが引数になってないでしょうに。 '件名',
'本文本文本文',
公表しているコードだとリテラル値を使っているだけなので、いきなり脳内情報を書き込まれてもわかりません。 >公表しているコードだとリテラル値を使っているだけなので、いきなり脳内情報を書き込まれてもわかりません。
すみません。引数をつけて書き直しました。
https://ideone.com/6Ufeev
>ネタじゃなければ、確認することをくっつけて実行するのは素人だと思ってください。
この件が、ソースコードのどの部分にあたるのか理解出来ていません。
おかしな理解のまま進みたくないので、教えて頂けないでしょうか。 グルグル回ってるな。
INSERTしたレコードの列値がすべてわかっているのに、そのレコードをSELECTするのはPostgreSQLを信用していないということなのか? idがストアドの中で採番されるからそれを取りたいんだろ。タイムスタンプなんかも。 SELECT文のFROM句にINSERTしてSELECTするファンクションを置きたい理由がわからない。
手続きをファンクションとして隠蔽したいんだろう。
idの最大値の求め方も同時実行の考慮なしだし、INSERTが想定通りだったか、自分で確認するらしいし、もはや目的がわからない。 >>984
>idの最大値の求め方も同時実行の考慮なしだし
SERIALIZABLEかもしれないよ INSERTが想定通りだったかSELECTで確認する
さらにそのSELECTが想定通りだったか・・・・詰み INSERT 時に採番される ID とタイムスタンプを取得したいので、ストアドプロシージャではなくストアドファンクションにしました。
ファンクションではトランザクションが使えないので、 serializable にする事で妥協しました。
全てのクエリが、ファンクションを呼び出すプログラム側 ( Npgsql ) の NpgsqlTransaction を使用するので、
プログラム側で IsolationLevel に Serializable を設定しています。
・ファンクションでトランザクションを使う方法
・ストアドプロシージャで戻り値を戻す方法
のいずれかが分かれば serializable 以外に出来るのですが、どうするべきなのかがよく分かりませんでした。 >>988
ネタじゃなく、知識がない状態で突貫でやらざるを得ない状態になっているのです・・・。 ストアドプロシージャにはOUTパラメータというものがあるんだよ Windowsの15.3をインストールしたけどpgadminが動かないね
海外の掲示板では15.2に戻せって言ってるっぽい
原因がPython側にあって修正する時間がないって回答きてるっぽいからしばらくバージョンアップ無理かな
やっぱネイティブじゃないとこんな事になっちゃうね どんな製品でも最新バージョンは様子見しておくもんなんだよ PostgreSQLは最新の15.3をインストール
添付のpgAdmin7.4はインストールしない
別途古いpgAdmin7.3をインストール
これでいけた Pgadmin4自体のデバッグログを出すにはどうしたら良いのでしょうか?
ググると「DBにxxの拡張を入れて〜」とかあるけど、そうじゃなくてpgadmin4のプログラム自体のログが見たいです。
AWSのrdsにssm経由で繋ごうとして、
psqlコマンドではpgpass.conf ファイルに設定したパスワードも読み込んで何も問題なく接続出来るんだけど、
psql -h localhost -p 57851 -U postgres -d postgres
pgadmin4ではconnection timeout expiredしか表示されなくて何も手がかりがなくて困ってます。
素のpsqlで繋がらないなら、DB側の設定やAWSのセキュリティグループを見るとかやりようはあるのでしょうが、pgadminだけで繋がらない状態です >>995
ありがとうございます。まさにここでした。
そしてログレベルを上げても接続エラーの詳細なログは出なくて
結局バックエンドのpythonにログを追加してデバッグして
最終的に接続できない理由はlocalhostと書いてあるからで127.0.0.1と書いたら繋がりました。 このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 2658日 17時間 26分 57秒 レス数が1000を超えています。これ以上書き込みはできません。